claude-threads 0.48.16 → 0.48.17

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/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.48.17] - 2026-01-09
11
+
12
+ ### Fixed
13
+ - **Typing indicator overflow** - Fixed text wrapping issue showing "eTyping..." on separate line, moved spinner after label (#147)
14
+ - **Excessive Slack logging** - Reduced API logging from sticky message cleanup with throttling (max once per 5 min) and time-based filtering (#148)
15
+
10
16
  ## [0.48.16] - 2026-01-09
11
17
 
12
18
  ### Added
package/dist/index.js CHANGED
@@ -43625,7 +43625,6 @@ class SlackClient extends EventEmitter2 {
43625
43625
  }
43626
43626
  throw new Error(`Slack API error: ${data.error}`);
43627
43627
  }
43628
- log2.debug(`API ${method} ${endpoint} -> ok`);
43629
43628
  return data;
43630
43629
  }
43631
43630
  async appApi(method, endpoint, body) {
@@ -44081,7 +44080,6 @@ class SlackClient extends EventEmitter2 {
44081
44080
  }
44082
44081
  async getPost(postId) {
44083
44082
  try {
44084
- log2.debug(`Fetching post ${postId.substring(0, 12)}`);
44085
44083
  const response = await this.api("GET", `conversations.history?channel=${this.channelId}&latest=${postId}&oldest=${postId}&inclusive=true&limit=1`);
44086
44084
  if (response.messages && response.messages.length > 0) {
44087
44085
  return this.normalizePlatformPost(response.messages[0], this.channelId);
@@ -53393,6 +53391,9 @@ var updateLocks = new Map;
53393
53391
  var sessionStore = null;
53394
53392
  var pausedPlatforms = new Map;
53395
53393
  var isShuttingDown = false;
53394
+ var lastCleanupTime = new Map;
53395
+ var CLEANUP_THROTTLE_MS = 5 * 60 * 1000;
53396
+ var CLEANUP_MAX_AGE_MS = 60 * 60 * 1000;
53396
53397
  function initialize(store) {
53397
53398
  sessionStore = store;
53398
53399
  const persistedIds = store.getStickyPostIds();
@@ -53741,14 +53742,36 @@ async function updateAllStickyMessages(platforms, sessions, config) {
53741
53742
  function markNeedsBump(platformId) {
53742
53743
  needsBump.set(platformId, true);
53743
53744
  }
53744
- async function cleanupOldStickyMessages(platform, botUserId) {
53745
- const currentStickyId = stickyPostIds.get(platform.platformId);
53745
+ function isRecentPost(postId) {
53746
+ const match = postId.match(/^(\d+)\.\d+$/);
53747
+ if (match) {
53748
+ const postTimestamp = parseInt(match[1], 10) * 1000;
53749
+ const age = Date.now() - postTimestamp;
53750
+ return age < CLEANUP_MAX_AGE_MS;
53751
+ }
53752
+ return true;
53753
+ }
53754
+ async function cleanupOldStickyMessages(platform, botUserId, forceRun = false) {
53755
+ const platformId = platform.platformId;
53756
+ const now = Date.now();
53757
+ if (!forceRun) {
53758
+ const lastRun = lastCleanupTime.get(platformId) || 0;
53759
+ if (now - lastRun < CLEANUP_THROTTLE_MS) {
53760
+ log17.debug(`Cleanup throttled for ${platformId} (last run ${Math.round((now - lastRun) / 1000)}s ago)`);
53761
+ return;
53762
+ }
53763
+ }
53764
+ lastCleanupTime.set(platformId, now);
53765
+ const currentStickyId = stickyPostIds.get(platformId);
53746
53766
  try {
53747
53767
  const pinnedPostIds = await platform.getPinnedPosts();
53748
- log17.debug(`Found ${pinnedPostIds.length} pinned posts, current sticky: ${currentStickyId?.substring(0, 8) || "(none)"}`);
53749
- for (const postId of pinnedPostIds) {
53750
- if (postId === currentStickyId)
53751
- continue;
53768
+ const recentPinnedIds = pinnedPostIds.filter((id) => id !== currentStickyId && isRecentPost(id));
53769
+ if (recentPinnedIds.length === 0) {
53770
+ log17.debug(`No recent pinned posts to check (${pinnedPostIds.length} total, current: ${currentStickyId?.substring(0, 8) || "(none)"})`);
53771
+ return;
53772
+ }
53773
+ log17.debug(`Checking ${recentPinnedIds.length} recent pinned posts (of ${pinnedPostIds.length} total)`);
53774
+ for (const postId of recentPinnedIds) {
53752
53775
  try {
53753
53776
  const post = await platform.getPost(postId);
53754
53777
  if (!post)
@@ -54343,12 +54366,13 @@ class SessionManager extends EventEmitter4 {
54343
54366
  initialize(this.sessionStore);
54344
54367
  await this.cleanupOrphanedWorktrees();
54345
54368
  for (const platform of this.platforms.values()) {
54346
- try {
54347
- const botUser = await platform.getBotUser();
54348
- await cleanupOldStickyMessages(platform, botUser.id);
54349
- } catch (err) {
54350
- log18.warn(`Failed to cleanup old sticky messages for ${platform.platformId}: ${err}`);
54351
- }
54369
+ platform.getBotUser().then((botUser) => {
54370
+ cleanupOldStickyMessages(platform, botUser.id, true).catch((err) => {
54371
+ log18.warn(`Failed to cleanup old sticky messages for ${platform.platformId}: ${err}`);
54372
+ });
54373
+ }).catch((err) => {
54374
+ log18.warn(`Failed to get bot user for cleanup on ${platform.platformId}: ${err}`);
54375
+ });
54352
54376
  }
54353
54377
  const staleIds = this.sessionStore.cleanStale(SESSION_TIMEOUT_MS * 2);
54354
54378
  if (staleIds.length > 0) {
@@ -63177,13 +63201,15 @@ var jsx_dev_runtime3 = __toESM(require_jsx_dev_runtime(), 1);
63177
63201
  function Spinner2({ label, type = "simpleDots" }) {
63178
63202
  return /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
63179
63203
  gap: 1,
63204
+ flexShrink: 0,
63180
63205
  children: [
63181
- /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Spinner, {
63182
- type
63183
- }, undefined, false, undefined, this),
63184
63206
  label && /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
63185
63207
  dimColor: true,
63208
+ wrap: "truncate",
63186
63209
  children: label
63210
+ }, undefined, false, undefined, this),
63211
+ /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Spinner, {
63212
+ type
63187
63213
  }, undefined, false, undefined, this)
63188
63214
  ]
63189
63215
  }, undefined, true, undefined, this);
@@ -63291,11 +63317,14 @@ function SessionLog({ logs, maxLines = 20 }) {
63291
63317
  }
63292
63318
  return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
63293
63319
  flexDirection: "column",
63320
+ flexShrink: 0,
63294
63321
  children: displayLogs.map((log19) => /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
63322
+ flexShrink: 0,
63295
63323
  children: [
63296
63324
  /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
63297
63325
  color: getColorForLevel(log19.level),
63298
63326
  dimColor: true,
63327
+ wrap: "truncate",
63299
63328
  children: [
63300
63329
  "[",
63301
63330
  padComponent(log19.component),
@@ -63304,6 +63333,7 @@ function SessionLog({ logs, maxLines = 20 }) {
63304
63333
  }, undefined, true, undefined, this),
63305
63334
  /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Text, {
63306
63335
  color: getColorForLevel(log19.level),
63336
+ wrap: "truncate",
63307
63337
  children: [
63308
63338
  " ",
63309
63339
  log19.message
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-threads",
3
- "version": "0.48.16",
3
+ "version": "0.48.17",
4
4
  "description": "Share Claude Code sessions live in a Mattermost channel with interactive features",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",