@hasna/conversations 0.2.55 → 0.2.57

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/bin/index.js CHANGED
@@ -14483,6 +14483,11 @@ function guessMimeType(name) {
14483
14483
  };
14484
14484
  return mimeMap[ext || ""] || "application/octet-stream";
14485
14485
  }
14486
+ function assertMessageSize(content) {
14487
+ if (Buffer.byteLength(content, "utf8") > MAX_MESSAGE_BYTES) {
14488
+ throw new Error(`Message content exceeds maximum size of ${MAX_MESSAGE_BYTES} bytes (64 KB).`);
14489
+ }
14490
+ }
14486
14491
  function checkRateLimit(agentId) {
14487
14492
  const dbPath = process.env.CONVERSATIONS_DB_PATH ?? process.env.HASNA_CONVERSATIONS_DB_PATH ?? "";
14488
14493
  if (dbPath === ":memory:" || dbPath.includes("test") || dbPath.includes("tmp"))
@@ -14499,9 +14504,7 @@ function checkRateLimit(agentId) {
14499
14504
  }
14500
14505
  }
14501
14506
  function sendMessage(opts) {
14502
- if (Buffer.byteLength(opts.content, "utf8") > MAX_MESSAGE_BYTES) {
14503
- throw new Error(`Message content exceeds maximum size of ${MAX_MESSAGE_BYTES} bytes (64 KB).`);
14504
- }
14507
+ assertMessageSize(opts.content);
14505
14508
  checkRateLimit(opts.from);
14506
14509
  const validatedAttachments = opts.attachments && opts.attachments.length > 0 ? opts.attachments.map((att) => validateAttachment(att.source_path, att.name)) : [];
14507
14510
  const db2 = getDb();
@@ -14773,6 +14776,7 @@ function deleteMessage(id, agent) {
14773
14776
  return result.changes > 0;
14774
14777
  }
14775
14778
  function editMessage(id, agent, newContent) {
14779
+ assertMessageSize(newContent);
14776
14780
  const db2 = getDb();
14777
14781
  const stmt = db2.prepare(`UPDATE messages SET content = ?, edited_at = strftime('%Y-%m-%dT%H:%M:%f', 'now') WHERE id = ? AND from_agent = ? RETURNING *`);
14778
14782
  const row = stmt.get(newContent, id, agent);
@@ -15549,7 +15553,7 @@ var init_space_notifications = __esm(() => {
15549
15553
  var require_package = __commonJS((exports, module) => {
15550
15554
  module.exports = {
15551
15555
  name: "@hasna/conversations",
15552
- version: "0.2.55",
15556
+ version: "0.2.57",
15553
15557
  description: "Real-time CLI messaging for AI agents",
15554
15558
  type: "module",
15555
15559
  bin: {
@@ -49909,6 +49913,44 @@ function normalizePort(value, fallback) {
49909
49913
  return fallback;
49910
49914
  return port;
49911
49915
  }
49916
+ function registryTimeoutMs() {
49917
+ const raw = process.env.CONVERSATIONS_REGISTRY_TIMEOUT_MS;
49918
+ if (!raw)
49919
+ return DEFAULT_REGISTRY_TIMEOUT_MS;
49920
+ const parsed = Number(raw);
49921
+ if (!Number.isFinite(parsed) || parsed <= 0)
49922
+ return DEFAULT_REGISTRY_TIMEOUT_MS;
49923
+ return Math.min(Math.ceil(parsed), MAX_REGISTRY_TIMEOUT_MS);
49924
+ }
49925
+ async function fetchLatestPackageVersion() {
49926
+ const timeoutMs = registryTimeoutMs();
49927
+ const controller = new AbortController;
49928
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
49929
+ try {
49930
+ const res = await fetch(NPM_LATEST_URL, {
49931
+ headers: { Accept: "application/json" },
49932
+ signal: controller.signal
49933
+ });
49934
+ if (!res.ok) {
49935
+ throw new Error(`npm registry responded with ${res.status}`);
49936
+ }
49937
+ const data = await res.json();
49938
+ if (typeof data.version !== "string" || !data.version) {
49939
+ throw new Error("npm registry response did not include a version");
49940
+ }
49941
+ return data.version;
49942
+ } catch (e) {
49943
+ if (controller.signal.aborted) {
49944
+ throw new RegistryTimeoutError(timeoutMs);
49945
+ }
49946
+ throw e;
49947
+ } finally {
49948
+ clearTimeout(timeout);
49949
+ }
49950
+ }
49951
+ function registryErrorStatus(e) {
49952
+ return e instanceof RegistryTimeoutError ? 504 : 500;
49953
+ }
49912
49954
  function isSameOrigin(req) {
49913
49955
  const origin = req.headers.get("origin");
49914
49956
  if (!origin)
@@ -50312,12 +50354,10 @@ function startDashboardServer(port = 0, host) {
50312
50354
  try {
50313
50355
  const pkg3 = await Promise.resolve().then(() => __toESM(require_package(), 1));
50314
50356
  const current = pkg3.version;
50315
- const res = await fetch("https://registry.npmjs.org/@hasna/conversations/latest");
50316
- const data = await res.json();
50317
- const latest = data.version;
50357
+ const latest = await fetchLatestPackageVersion();
50318
50358
  return jsonResponse({ current, latest, updateAvailable: current !== latest });
50319
50359
  } catch (e) {
50320
- return jsonResponse({ error: e.message }, 500);
50360
+ return jsonResponse({ error: e.message }, registryErrorStatus(e));
50321
50361
  }
50322
50362
  }
50323
50363
  if (path === "/api/update" && req.method === "POST") {
@@ -50327,9 +50367,7 @@ function startDashboardServer(port = 0, host) {
50327
50367
  try {
50328
50368
  const pkg3 = await Promise.resolve().then(() => __toESM(require_package(), 1));
50329
50369
  const current = pkg3.version;
50330
- const res = await fetch("https://registry.npmjs.org/@hasna/conversations/latest");
50331
- const data = await res.json();
50332
- const latest = data.version;
50370
+ const latest = await fetchLatestPackageVersion();
50333
50371
  if (current === latest) {
50334
50372
  return jsonResponse({ current, latest, status: "up-to-date" });
50335
50373
  }
@@ -50346,7 +50384,7 @@ function startDashboardServer(port = 0, host) {
50346
50384
  return jsonResponse({ current, latest, status: "failed", exitCode, stderr }, 500);
50347
50385
  }
50348
50386
  } catch (e) {
50349
- return jsonResponse({ error: e.message }, 500);
50387
+ return jsonResponse({ error: e.message }, registryErrorStatus(e));
50350
50388
  }
50351
50389
  }
50352
50390
  if (dashboardDist) {
@@ -50380,7 +50418,7 @@ function startDashboardServer(port = 0, host) {
50380
50418
  console.log(`Dashboard running at http://localhost:${server2.port}`);
50381
50419
  return server2;
50382
50420
  }
50383
- var isDirectRun2;
50421
+ var NPM_LATEST_URL = "https://registry.npmjs.org/@hasna/conversations/latest", DEFAULT_REGISTRY_TIMEOUT_MS = 3000, MAX_REGISTRY_TIMEOUT_MS = 30000, RegistryTimeoutError, isDirectRun2;
50384
50422
  var init_serve = __esm(() => {
50385
50423
  init_messages();
50386
50424
  init_sessions();
@@ -50394,6 +50432,12 @@ var init_serve = __esm(() => {
50394
50432
  init_locks();
50395
50433
  init_http();
50396
50434
  init_mcp2();
50435
+ RegistryTimeoutError = class RegistryTimeoutError extends Error {
50436
+ constructor(timeoutMs) {
50437
+ super(`npm registry request timed out after ${timeoutMs}ms`);
50438
+ this.name = "RegistryTimeoutError";
50439
+ }
50440
+ };
50397
50441
  isDirectRun2 = import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith("serve.ts") || process.argv[1]?.endsWith("serve.js");
50398
50442
  if (isDirectRun2) {
50399
50443
  const port = normalizePort(process.env.PORT, 0);
package/bin/mcp.js CHANGED
@@ -41141,6 +41141,11 @@ function guessMimeType(name) {
41141
41141
  return mimeMap[ext || ""] || "application/octet-stream";
41142
41142
  }
41143
41143
  var MAX_MESSAGE_BYTES = 65536;
41144
+ function assertMessageSize(content) {
41145
+ if (Buffer.byteLength(content, "utf8") > MAX_MESSAGE_BYTES) {
41146
+ throw new Error(`Message content exceeds maximum size of ${MAX_MESSAGE_BYTES} bytes (64 KB).`);
41147
+ }
41148
+ }
41144
41149
  var RATE_LIMIT_MAX = 60;
41145
41150
  var RATE_LIMIT_WINDOW_MS = 60000;
41146
41151
  var _rateLimitCounters = new Map;
@@ -41160,9 +41165,7 @@ function checkRateLimit(agentId) {
41160
41165
  }
41161
41166
  }
41162
41167
  function sendMessage(opts) {
41163
- if (Buffer.byteLength(opts.content, "utf8") > MAX_MESSAGE_BYTES) {
41164
- throw new Error(`Message content exceeds maximum size of ${MAX_MESSAGE_BYTES} bytes (64 KB).`);
41165
- }
41168
+ assertMessageSize(opts.content);
41166
41169
  checkRateLimit(opts.from);
41167
41170
  const validatedAttachments = opts.attachments && opts.attachments.length > 0 ? opts.attachments.map((att) => validateAttachment(att.source_path, att.name)) : [];
41168
41171
  const db2 = getDb();
@@ -41428,6 +41431,7 @@ function deleteMessage(id, agent) {
41428
41431
  return result.changes > 0;
41429
41432
  }
41430
41433
  function editMessage(id, agent, newContent) {
41434
+ assertMessageSize(newContent);
41431
41435
  const db2 = getDb();
41432
41436
  const stmt = db2.prepare(`UPDATE messages SET content = ?, edited_at = strftime('%Y-%m-%dT%H:%M:%f', 'now') WHERE id = ? AND from_agent = ? RETURNING *`);
41433
41437
  const row = stmt.get(newContent, id, agent);
@@ -46900,7 +46904,7 @@ function startMcpHttpServer(options) {
46900
46904
  // package.json
46901
46905
  var package_default = {
46902
46906
  name: "@hasna/conversations",
46903
- version: "0.2.55",
46907
+ version: "0.2.57",
46904
46908
  description: "Real-time CLI messaging for AI agents",
46905
46909
  type: "module",
46906
46910
  bin: {
package/dist/index.js CHANGED
@@ -12142,6 +12142,11 @@ function guessMimeType(name) {
12142
12142
  return mimeMap[ext || ""] || "application/octet-stream";
12143
12143
  }
12144
12144
  var MAX_MESSAGE_BYTES = 65536;
12145
+ function assertMessageSize(content) {
12146
+ if (Buffer.byteLength(content, "utf8") > MAX_MESSAGE_BYTES) {
12147
+ throw new Error(`Message content exceeds maximum size of ${MAX_MESSAGE_BYTES} bytes (64 KB).`);
12148
+ }
12149
+ }
12145
12150
  var RATE_LIMIT_MAX = 60;
12146
12151
  var RATE_LIMIT_WINDOW_MS = 60000;
12147
12152
  var _rateLimitCounters = new Map;
@@ -12161,9 +12166,7 @@ function checkRateLimit(agentId) {
12161
12166
  }
12162
12167
  }
12163
12168
  function sendMessage(opts) {
12164
- if (Buffer.byteLength(opts.content, "utf8") > MAX_MESSAGE_BYTES) {
12165
- throw new Error(`Message content exceeds maximum size of ${MAX_MESSAGE_BYTES} bytes (64 KB).`);
12166
- }
12169
+ assertMessageSize(opts.content);
12167
12170
  checkRateLimit(opts.from);
12168
12171
  const validatedAttachments = opts.attachments && opts.attachments.length > 0 ? opts.attachments.map((att) => validateAttachment(att.source_path, att.name)) : [];
12169
12172
  const db2 = getDb();
@@ -12373,6 +12376,7 @@ function deleteMessage(id, agent) {
12373
12376
  return result.changes > 0;
12374
12377
  }
12375
12378
  function editMessage(id, agent, newContent) {
12379
+ assertMessageSize(newContent);
12376
12380
  const db2 = getDb();
12377
12381
  const stmt = db2.prepare(`UPDATE messages SET content = ?, edited_at = strftime('%Y-%m-%dT%H:%M:%f', 'now') WHERE id = ? AND from_agent = ? RETURNING *`);
12378
12382
  const row = stmt.get(newContent, id, agent);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/conversations",
3
- "version": "0.2.55",
3
+ "version": "0.2.57",
4
4
  "description": "Real-time CLI messaging for AI agents",
5
5
  "type": "module",
6
6
  "bin": {