claude-threads 1.3.1 → 1.3.2
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 +10 -0
- package/dist/index.js +107 -93
- package/dist/mcp/permission-server.js +3125 -3122
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.3.2] - 2026-01-17
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **Clearer version display** - Status bars now show `CT v1.3.2 · CC v2.1.12` instead of `v1.3.2 · CLI 2.1.12` (#232)
|
|
12
|
+
- CT = claude-threads (this bot)
|
|
13
|
+
- CC = Claude Code (the CLI)
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- **Resolve ESLint warnings** - Fix 5 `no-non-null-assertion` lint warnings (#233)
|
|
17
|
+
|
|
8
18
|
## [1.3.1] - 2026-01-17
|
|
9
19
|
|
|
10
20
|
### Fixed
|
package/dist/index.js
CHANGED
|
@@ -49566,6 +49566,15 @@ function validateClaudeCli() {
|
|
|
49566
49566
|
rawOutput: result.rawOutput
|
|
49567
49567
|
};
|
|
49568
49568
|
}
|
|
49569
|
+
if (!result.version) {
|
|
49570
|
+
return {
|
|
49571
|
+
installed: true,
|
|
49572
|
+
version: null,
|
|
49573
|
+
compatible: true,
|
|
49574
|
+
message: "Claude CLI found (version unknown)",
|
|
49575
|
+
rawOutput: result.rawOutput ?? undefined
|
|
49576
|
+
};
|
|
49577
|
+
}
|
|
49569
49578
|
const compatible = isVersionCompatible(result.version);
|
|
49570
49579
|
if (!compatible) {
|
|
49571
49580
|
return {
|
|
@@ -51029,6 +51038,33 @@ class BasePlatformClient extends EventEmitter {
|
|
|
51029
51038
|
this.lastMessageAt = Date.now();
|
|
51030
51039
|
}
|
|
51031
51040
|
}
|
|
51041
|
+
// src/version.ts
|
|
51042
|
+
import { readFileSync as readFileSync3, existsSync as existsSync4 } from "fs";
|
|
51043
|
+
import { dirname as dirname3, resolve as resolve2 } from "path";
|
|
51044
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
51045
|
+
var __dirname3 = dirname3(fileURLToPath2(import.meta.url));
|
|
51046
|
+
function loadPackageJson() {
|
|
51047
|
+
const candidates = [
|
|
51048
|
+
resolve2(__dirname3, "..", "package.json"),
|
|
51049
|
+
resolve2(__dirname3, "..", "..", "package.json"),
|
|
51050
|
+
resolve2(process.cwd(), "package.json")
|
|
51051
|
+
];
|
|
51052
|
+
for (const candidate of candidates) {
|
|
51053
|
+
if (existsSync4(candidate)) {
|
|
51054
|
+
try {
|
|
51055
|
+
const pkg = JSON.parse(readFileSync3(candidate, "utf-8"));
|
|
51056
|
+
if (pkg.name === "claude-threads") {
|
|
51057
|
+
return { version: pkg.version, name: pkg.name };
|
|
51058
|
+
}
|
|
51059
|
+
} catch {}
|
|
51060
|
+
}
|
|
51061
|
+
}
|
|
51062
|
+
return { version: "unknown", name: "claude-threads" };
|
|
51063
|
+
}
|
|
51064
|
+
var pkgInfo = loadPackageJson();
|
|
51065
|
+
var VERSION = pkgInfo.version;
|
|
51066
|
+
var PKG = pkgInfo;
|
|
51067
|
+
|
|
51032
51068
|
// src/utils/format.ts
|
|
51033
51069
|
function extractThreadId(sessionId) {
|
|
51034
51070
|
const colonIndex = sessionId.indexOf(":");
|
|
@@ -51068,6 +51104,10 @@ function formatRelativeTimeShort(date) {
|
|
|
51068
51104
|
return `${minutes}m ago`;
|
|
51069
51105
|
return "<1m ago";
|
|
51070
51106
|
}
|
|
51107
|
+
function formatVersionString() {
|
|
51108
|
+
const claudeVersion = getClaudeCliVersion().version;
|
|
51109
|
+
return claudeVersion ? `CT v${VERSION} · CC v${claudeVersion}` : `CT v${VERSION}`;
|
|
51110
|
+
}
|
|
51071
51111
|
function truncateAtWord(str2, maxLength) {
|
|
51072
51112
|
if (str2.length <= maxLength)
|
|
51073
51113
|
return str2;
|
|
@@ -51359,13 +51399,14 @@ class MattermostClient extends BasePlatformClient {
|
|
|
51359
51399
|
};
|
|
51360
51400
|
}
|
|
51361
51401
|
async processAndEmitPost(post) {
|
|
51362
|
-
const
|
|
51402
|
+
const fileIds = post.file_ids;
|
|
51403
|
+
const hasFileIds = fileIds && fileIds.length > 0;
|
|
51363
51404
|
const hasFileMetadata = post.metadata?.files && post.metadata.files.length > 0;
|
|
51364
51405
|
if (hasFileIds && !hasFileMetadata) {
|
|
51365
|
-
log2.debug(`Post ${formatShortId(post.id)} has ${
|
|
51406
|
+
log2.debug(`Post ${formatShortId(post.id)} has ${fileIds.length} file(s), fetching metadata`);
|
|
51366
51407
|
try {
|
|
51367
51408
|
const files = [];
|
|
51368
|
-
for (const fileId of
|
|
51409
|
+
for (const fileId of fileIds) {
|
|
51369
51410
|
try {
|
|
51370
51411
|
const file = await this.api("GET", `/files/${fileId}/info`);
|
|
51371
51412
|
files.push(file);
|
|
@@ -51409,7 +51450,7 @@ class MattermostClient extends BasePlatformClient {
|
|
|
51409
51450
|
if (response.status === 500 && retryCount < this.MAX_RETRIES) {
|
|
51410
51451
|
const delay = this.RETRY_DELAY_MS * Math.pow(2, retryCount);
|
|
51411
51452
|
log2.warn(`API ${method} ${path} failed with 500, retrying in ${delay}ms (attempt ${retryCount + 1}/${this.MAX_RETRIES})`);
|
|
51412
|
-
await new Promise((
|
|
51453
|
+
await new Promise((resolve3) => setTimeout(resolve3, delay));
|
|
51413
51454
|
return this.api(method, path, body, retryCount + 1, options2);
|
|
51414
51455
|
}
|
|
51415
51456
|
const isSilent = options2?.silent?.includes(response.status);
|
|
@@ -51595,7 +51636,7 @@ class MattermostClient extends BasePlatformClient {
|
|
|
51595
51636
|
await this.getBotUser();
|
|
51596
51637
|
wsLogger.debug(`Bot user ID: ${this.botUserId}`);
|
|
51597
51638
|
const wsUrl = this.url.replace(/^http/, "ws").concat("/api/v4/websocket");
|
|
51598
|
-
return new Promise((
|
|
51639
|
+
return new Promise((resolve3, reject) => {
|
|
51599
51640
|
this.ws = new WebSocket(wsUrl);
|
|
51600
51641
|
this.ws.onopen = () => {
|
|
51601
51642
|
wsLogger.info("WebSocket connected, sending auth challenge");
|
|
@@ -51616,7 +51657,7 @@ class MattermostClient extends BasePlatformClient {
|
|
|
51616
51657
|
this.handleEvent(wsEvent);
|
|
51617
51658
|
if (wsEvent.event === "hello") {
|
|
51618
51659
|
this.onConnectionEstablished();
|
|
51619
|
-
|
|
51660
|
+
resolve3();
|
|
51620
51661
|
}
|
|
51621
51662
|
} catch (err) {
|
|
51622
51663
|
wsLogger.warn(`Failed to parse message: ${err}`);
|
|
@@ -51900,7 +51941,7 @@ class SlackClient extends BasePlatformClient {
|
|
|
51900
51941
|
if (now < this.rateLimitRetryAfter) {
|
|
51901
51942
|
const waitTime = this.rateLimitRetryAfter - now;
|
|
51902
51943
|
log3.debug(`Rate limited, waiting ${waitTime}ms`);
|
|
51903
|
-
await new Promise((
|
|
51944
|
+
await new Promise((resolve3) => setTimeout(resolve3, waitTime));
|
|
51904
51945
|
}
|
|
51905
51946
|
this.rateLimitDelay = 0;
|
|
51906
51947
|
}
|
|
@@ -51924,7 +51965,7 @@ class SlackClient extends BasePlatformClient {
|
|
|
51924
51965
|
this.rateLimitDelay = retryAfter * 1000;
|
|
51925
51966
|
this.rateLimitRetryAfter = Date.now() + this.rateLimitDelay;
|
|
51926
51967
|
log3.warn(`Rate limited by Slack, retrying after ${retryAfter}s (attempt ${retryCount + 1}/${this.MAX_RATE_LIMIT_RETRIES})`);
|
|
51927
|
-
await new Promise((
|
|
51968
|
+
await new Promise((resolve3) => setTimeout(resolve3, this.rateLimitDelay));
|
|
51928
51969
|
return this.api(method, endpoint, body, retryCount + 1);
|
|
51929
51970
|
}
|
|
51930
51971
|
if (!response.ok) {
|
|
@@ -51969,12 +52010,12 @@ class SlackClient extends BasePlatformClient {
|
|
|
51969
52010
|
const response = await this.appApi("POST", "apps.connections.open");
|
|
51970
52011
|
const wsUrl = response.url;
|
|
51971
52012
|
wsLogger.info("Socket Mode: Got WebSocket URL, connecting...");
|
|
51972
|
-
return new Promise((
|
|
52013
|
+
return new Promise((resolve3, reject) => {
|
|
51973
52014
|
let settled = false;
|
|
51974
52015
|
const doResolve = () => {
|
|
51975
52016
|
if (!settled) {
|
|
51976
52017
|
settled = true;
|
|
51977
|
-
|
|
52018
|
+
resolve3();
|
|
51978
52019
|
}
|
|
51979
52020
|
};
|
|
51980
52021
|
const doReject = (err) => {
|
|
@@ -52592,7 +52633,7 @@ class MattermostPermissionApi {
|
|
|
52592
52633
|
await updatePost(this.apiConfig, postId, message);
|
|
52593
52634
|
}
|
|
52594
52635
|
async waitForReaction(postId, botUserId, timeoutMs) {
|
|
52595
|
-
return new Promise((
|
|
52636
|
+
return new Promise((resolve3) => {
|
|
52596
52637
|
const wsUrl = this.config.url.replace(/^http/, "ws") + "/api/v4/websocket";
|
|
52597
52638
|
mcpLogger.debug(`Connecting to WebSocket: ${wsUrl}`);
|
|
52598
52639
|
const ws = new WebSocket(wsUrl);
|
|
@@ -52607,7 +52648,7 @@ class MattermostPermissionApi {
|
|
|
52607
52648
|
mcpLogger.debug(`Reaction wait timed out after ${timeoutMs}ms`);
|
|
52608
52649
|
resolved = true;
|
|
52609
52650
|
cleanup();
|
|
52610
|
-
|
|
52651
|
+
resolve3(null);
|
|
52611
52652
|
}
|
|
52612
52653
|
}, timeoutMs);
|
|
52613
52654
|
ws.onopen = () => {
|
|
@@ -52635,7 +52676,7 @@ class MattermostPermissionApi {
|
|
|
52635
52676
|
resolved = true;
|
|
52636
52677
|
clearTimeout(timeout);
|
|
52637
52678
|
cleanup();
|
|
52638
|
-
|
|
52679
|
+
resolve3({
|
|
52639
52680
|
postId: reaction.post_id,
|
|
52640
52681
|
userId: reaction.user_id,
|
|
52641
52682
|
emojiName: reaction.emoji_name
|
|
@@ -52650,7 +52691,7 @@ class MattermostPermissionApi {
|
|
|
52650
52691
|
if (!resolved) {
|
|
52651
52692
|
resolved = true;
|
|
52652
52693
|
clearTimeout(timeout);
|
|
52653
|
-
|
|
52694
|
+
resolve3(null);
|
|
52654
52695
|
}
|
|
52655
52696
|
};
|
|
52656
52697
|
ws.onclose = () => {
|
|
@@ -52658,7 +52699,7 @@ class MattermostPermissionApi {
|
|
|
52658
52699
|
if (!resolved) {
|
|
52659
52700
|
resolved = true;
|
|
52660
52701
|
clearTimeout(timeout);
|
|
52661
|
-
|
|
52702
|
+
resolve3(null);
|
|
52662
52703
|
}
|
|
52663
52704
|
};
|
|
52664
52705
|
});
|
|
@@ -52766,7 +52807,7 @@ class SlackPermissionApi {
|
|
|
52766
52807
|
});
|
|
52767
52808
|
}
|
|
52768
52809
|
async waitForReaction(postId, botUserId, timeoutMs) {
|
|
52769
|
-
return new Promise((
|
|
52810
|
+
return new Promise((resolve3) => {
|
|
52770
52811
|
let resolved = false;
|
|
52771
52812
|
let ws = null;
|
|
52772
52813
|
const cleanup = () => {
|
|
@@ -52779,7 +52820,7 @@ class SlackPermissionApi {
|
|
|
52779
52820
|
mcpLogger.debug(`Reaction wait timed out after ${timeoutMs}ms`);
|
|
52780
52821
|
resolved = true;
|
|
52781
52822
|
cleanup();
|
|
52782
|
-
|
|
52823
|
+
resolve3(null);
|
|
52783
52824
|
}
|
|
52784
52825
|
}, timeoutMs);
|
|
52785
52826
|
this.getSocketModeUrl().then((wsUrl) => {
|
|
@@ -52817,7 +52858,7 @@ class SlackPermissionApi {
|
|
|
52817
52858
|
resolved = true;
|
|
52818
52859
|
clearTimeout(timeout);
|
|
52819
52860
|
cleanup();
|
|
52820
|
-
|
|
52861
|
+
resolve3({
|
|
52821
52862
|
postId: item.ts,
|
|
52822
52863
|
userId,
|
|
52823
52864
|
emojiName
|
|
@@ -52833,7 +52874,7 @@ class SlackPermissionApi {
|
|
|
52833
52874
|
resolved = true;
|
|
52834
52875
|
clearTimeout(timeout);
|
|
52835
52876
|
cleanup();
|
|
52836
|
-
|
|
52877
|
+
resolve3(null);
|
|
52837
52878
|
}
|
|
52838
52879
|
}
|
|
52839
52880
|
} catch (err) {
|
|
@@ -52846,7 +52887,7 @@ class SlackPermissionApi {
|
|
|
52846
52887
|
resolved = true;
|
|
52847
52888
|
clearTimeout(timeout);
|
|
52848
52889
|
cleanup();
|
|
52849
|
-
|
|
52890
|
+
resolve3(null);
|
|
52850
52891
|
}
|
|
52851
52892
|
};
|
|
52852
52893
|
ws.onclose = () => {
|
|
@@ -52854,7 +52895,7 @@ class SlackPermissionApi {
|
|
|
52854
52895
|
if (!resolved) {
|
|
52855
52896
|
resolved = true;
|
|
52856
52897
|
clearTimeout(timeout);
|
|
52857
|
-
|
|
52898
|
+
resolve3(null);
|
|
52858
52899
|
}
|
|
52859
52900
|
};
|
|
52860
52901
|
}).catch((err) => {
|
|
@@ -52862,7 +52903,7 @@ class SlackPermissionApi {
|
|
|
52862
52903
|
if (!resolved) {
|
|
52863
52904
|
resolved = true;
|
|
52864
52905
|
clearTimeout(timeout);
|
|
52865
|
-
|
|
52906
|
+
resolve3(null);
|
|
52866
52907
|
}
|
|
52867
52908
|
});
|
|
52868
52909
|
});
|
|
@@ -52878,7 +52919,7 @@ class SlackPermissionApi {
|
|
|
52878
52919
|
import { EventEmitter as EventEmitter4 } from "events";
|
|
52879
52920
|
|
|
52880
52921
|
// src/persistence/session-store.ts
|
|
52881
|
-
import { existsSync as
|
|
52922
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync4, writeFileSync as writeFileSync2, renameSync } from "fs";
|
|
52882
52923
|
import { homedir as homedir2 } from "os";
|
|
52883
52924
|
import { join as join2 } from "path";
|
|
52884
52925
|
var log5 = createLogger("persist");
|
|
@@ -52899,18 +52940,18 @@ class SessionStore {
|
|
|
52899
52940
|
this.sessionsFile = DEFAULT_SESSIONS_FILE;
|
|
52900
52941
|
this.configDir = DEFAULT_CONFIG_DIR;
|
|
52901
52942
|
}
|
|
52902
|
-
if (!
|
|
52943
|
+
if (!existsSync5(this.configDir)) {
|
|
52903
52944
|
mkdirSync2(this.configDir, { recursive: true });
|
|
52904
52945
|
}
|
|
52905
52946
|
}
|
|
52906
52947
|
load() {
|
|
52907
52948
|
const sessions = new Map;
|
|
52908
|
-
if (!
|
|
52949
|
+
if (!existsSync5(this.sessionsFile)) {
|
|
52909
52950
|
log5.debug("No sessions file found");
|
|
52910
52951
|
return sessions;
|
|
52911
52952
|
}
|
|
52912
52953
|
try {
|
|
52913
|
-
const data = JSON.parse(
|
|
52954
|
+
const data = JSON.parse(readFileSync4(this.sessionsFile, "utf-8"));
|
|
52914
52955
|
if (data.version === 1) {
|
|
52915
52956
|
log5.info("Migrating sessions from v1 to v2 (adding platformId)");
|
|
52916
52957
|
const newSessions = {};
|
|
@@ -53084,11 +53125,11 @@ class SessionStore {
|
|
|
53084
53125
|
return;
|
|
53085
53126
|
}
|
|
53086
53127
|
loadRaw() {
|
|
53087
|
-
if (!
|
|
53128
|
+
if (!existsSync5(this.sessionsFile)) {
|
|
53088
53129
|
return { version: STORE_VERSION, sessions: {} };
|
|
53089
53130
|
}
|
|
53090
53131
|
try {
|
|
53091
|
-
return JSON.parse(
|
|
53132
|
+
return JSON.parse(readFileSync4(this.sessionsFile, "utf-8"));
|
|
53092
53133
|
} catch {
|
|
53093
53134
|
return { version: STORE_VERSION, sessions: {} };
|
|
53094
53135
|
}
|
|
@@ -53103,14 +53144,14 @@ class SessionStore {
|
|
|
53103
53144
|
init_emoji();
|
|
53104
53145
|
|
|
53105
53146
|
// src/cleanup/scheduler.ts
|
|
53106
|
-
import { existsSync as
|
|
53147
|
+
import { existsSync as existsSync7 } from "fs";
|
|
53107
53148
|
import { readdir, rm } from "fs/promises";
|
|
53108
53149
|
import { join as join5 } from "path";
|
|
53109
53150
|
|
|
53110
53151
|
// src/persistence/thread-logger.ts
|
|
53111
|
-
import { existsSync as
|
|
53152
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync3, appendFileSync, readdirSync, statSync, unlinkSync, rmdirSync, readFileSync as readFileSync5 } from "fs";
|
|
53112
53153
|
import { homedir as homedir3 } from "os";
|
|
53113
|
-
import { join as join3, dirname as
|
|
53154
|
+
import { join as join3, dirname as dirname4 } from "path";
|
|
53114
53155
|
var log6 = createLogger("thread-log");
|
|
53115
53156
|
var LOGS_BASE_DIR = join3(homedir3(), ".claude-threads", "logs");
|
|
53116
53157
|
|
|
@@ -53134,8 +53175,8 @@ class ThreadLoggerImpl {
|
|
|
53134
53175
|
this.flushIntervalMs = options2?.flushIntervalMs ?? 1000;
|
|
53135
53176
|
this.logPath = join3(LOGS_BASE_DIR, platformId, `${claudeSessionId}.jsonl`);
|
|
53136
53177
|
if (this.enabled) {
|
|
53137
|
-
const dir =
|
|
53138
|
-
if (!
|
|
53178
|
+
const dir = dirname4(this.logPath);
|
|
53179
|
+
if (!existsSync6(dir)) {
|
|
53139
53180
|
mkdirSync3(dir, { recursive: true });
|
|
53140
53181
|
}
|
|
53141
53182
|
this.flushTimer = setInterval(() => {
|
|
@@ -53304,7 +53345,7 @@ function createThreadLogger(platformId, threadId, claudeSessionId, options2) {
|
|
|
53304
53345
|
function cleanupOldLogs(retentionDays = 30) {
|
|
53305
53346
|
const cutoffMs = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
|
|
53306
53347
|
let deletedCount = 0;
|
|
53307
|
-
if (!
|
|
53348
|
+
if (!existsSync6(LOGS_BASE_DIR)) {
|
|
53308
53349
|
return 0;
|
|
53309
53350
|
}
|
|
53310
53351
|
try {
|
|
@@ -53352,12 +53393,12 @@ function getLogFilePath(platformId, sessionId) {
|
|
|
53352
53393
|
function readRecentLogEntries(platformId, sessionId, maxLines = 50) {
|
|
53353
53394
|
const logPath = getLogFilePath(platformId, sessionId);
|
|
53354
53395
|
log6.debug(`Reading log entries from: ${logPath}`);
|
|
53355
|
-
if (!
|
|
53396
|
+
if (!existsSync6(logPath)) {
|
|
53356
53397
|
log6.debug(`Log file does not exist: ${logPath}`);
|
|
53357
53398
|
return [];
|
|
53358
53399
|
}
|
|
53359
53400
|
try {
|
|
53360
|
-
const content =
|
|
53401
|
+
const content = readFileSync5(logPath, "utf8");
|
|
53361
53402
|
const lines = content.trim().split(`
|
|
53362
53403
|
`);
|
|
53363
53404
|
log6.debug(`Log file has ${lines.length} lines`);
|
|
@@ -53389,7 +53430,7 @@ var WORKTREES_DIR = path.join(homedir4(), ".claude-threads", "worktrees");
|
|
|
53389
53430
|
async function execGit(args, cwd) {
|
|
53390
53431
|
const cmd = `git ${args.join(" ")}`;
|
|
53391
53432
|
log7.debug(`Executing: ${cmd}`);
|
|
53392
|
-
return new Promise((
|
|
53433
|
+
return new Promise((resolve3, reject) => {
|
|
53393
53434
|
const proc = spawn2("git", args, { cwd });
|
|
53394
53435
|
let stdout = "";
|
|
53395
53436
|
let stderr = "";
|
|
@@ -53402,7 +53443,7 @@ async function execGit(args, cwd) {
|
|
|
53402
53443
|
proc.on("close", (code) => {
|
|
53403
53444
|
if (code === 0) {
|
|
53404
53445
|
log7.debug(`${cmd} → success`);
|
|
53405
|
-
|
|
53446
|
+
resolve3(stdout.trim());
|
|
53406
53447
|
} else {
|
|
53407
53448
|
log7.debug(`${cmd} → failed (code=${code}): ${stderr.substring(0, 100) || stdout.substring(0, 100)}`);
|
|
53408
53449
|
reject(new Error(`git ${args.join(" ")} failed: ${stderr || stdout}`));
|
|
@@ -53763,20 +53804,20 @@ class CleanupScheduler {
|
|
|
53763
53804
|
if (!this.threadLogsEnabled) {
|
|
53764
53805
|
return 0;
|
|
53765
53806
|
}
|
|
53766
|
-
return new Promise((
|
|
53807
|
+
return new Promise((resolve3) => {
|
|
53767
53808
|
try {
|
|
53768
53809
|
const deleted = cleanupOldLogs(this.logRetentionDays);
|
|
53769
|
-
|
|
53810
|
+
resolve3(deleted);
|
|
53770
53811
|
} catch (err) {
|
|
53771
53812
|
log8.warn(`Log cleanup error: ${err}`);
|
|
53772
|
-
|
|
53813
|
+
resolve3(0);
|
|
53773
53814
|
}
|
|
53774
53815
|
});
|
|
53775
53816
|
}
|
|
53776
53817
|
async cleanupOrphanedWorktrees() {
|
|
53777
53818
|
const worktreesDir = getWorktreesDir();
|
|
53778
53819
|
const result = { cleaned: 0, metadata: 0 };
|
|
53779
|
-
if (!
|
|
53820
|
+
if (!existsSync7(worktreesDir)) {
|
|
53780
53821
|
log8.debug("No worktrees directory exists, nothing to clean");
|
|
53781
53822
|
return result;
|
|
53782
53823
|
}
|
|
@@ -53916,9 +53957,9 @@ function getSessionStatus(session) {
|
|
|
53916
53957
|
// src/claude/cli.ts
|
|
53917
53958
|
import { spawn as spawn3 } from "child_process";
|
|
53918
53959
|
import { EventEmitter as EventEmitter2 } from "events";
|
|
53919
|
-
import { resolve as
|
|
53920
|
-
import { fileURLToPath as
|
|
53921
|
-
import { existsSync as
|
|
53960
|
+
import { resolve as resolve3, dirname as dirname6 } from "path";
|
|
53961
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
53962
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, watchFile, unwatchFile, unlinkSync as unlinkSync2, statSync as statSync2, readdirSync as readdirSync2 } from "fs";
|
|
53922
53963
|
import { tmpdir } from "os";
|
|
53923
53964
|
import { join as join6 } from "path";
|
|
53924
53965
|
var log9 = createLogger("claude");
|
|
@@ -53964,8 +54005,8 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53964
54005
|
if (!this.statusFilePath)
|
|
53965
54006
|
return null;
|
|
53966
54007
|
try {
|
|
53967
|
-
if (
|
|
53968
|
-
const data =
|
|
54008
|
+
if (existsSync8(this.statusFilePath)) {
|
|
54009
|
+
const data = readFileSync6(this.statusFilePath, "utf8");
|
|
53969
54010
|
this.lastStatusData = JSON.parse(data);
|
|
53970
54011
|
}
|
|
53971
54012
|
} catch (err) {
|
|
@@ -53992,7 +54033,7 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53992
54033
|
if (this.statusFilePath) {
|
|
53993
54034
|
unwatchFile(this.statusFilePath);
|
|
53994
54035
|
try {
|
|
53995
|
-
if (
|
|
54036
|
+
if (existsSync8(this.statusFilePath)) {
|
|
53996
54037
|
unlinkSync2(this.statusFilePath);
|
|
53997
54038
|
}
|
|
53998
54039
|
} catch {}
|
|
@@ -54180,7 +54221,7 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
54180
54221
|
const pid = proc.pid;
|
|
54181
54222
|
this.process = null;
|
|
54182
54223
|
this.log.debug(`Killing Claude process (pid=${pid})`);
|
|
54183
|
-
return new Promise((
|
|
54224
|
+
return new Promise((resolve4) => {
|
|
54184
54225
|
this.log.debug("Sending first SIGINT");
|
|
54185
54226
|
proc.kill("SIGINT");
|
|
54186
54227
|
const secondSigint = setTimeout(() => {
|
|
@@ -54199,7 +54240,7 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
54199
54240
|
this.log.debug(`Claude process exited (code=${code})`);
|
|
54200
54241
|
clearTimeout(secondSigint);
|
|
54201
54242
|
clearTimeout(forceKillTimeout);
|
|
54202
|
-
|
|
54243
|
+
resolve4();
|
|
54203
54244
|
});
|
|
54204
54245
|
});
|
|
54205
54246
|
}
|
|
@@ -54213,44 +54254,17 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
54213
54254
|
return true;
|
|
54214
54255
|
}
|
|
54215
54256
|
getMcpServerPath() {
|
|
54216
|
-
const __filename2 =
|
|
54217
|
-
const
|
|
54218
|
-
return
|
|
54257
|
+
const __filename2 = fileURLToPath3(import.meta.url);
|
|
54258
|
+
const __dirname4 = dirname6(__filename2);
|
|
54259
|
+
return resolve3(__dirname4, "..", "mcp", "permission-server.js");
|
|
54219
54260
|
}
|
|
54220
54261
|
getStatusLineWriterPath() {
|
|
54221
|
-
const __filename2 =
|
|
54222
|
-
const
|
|
54223
|
-
return
|
|
54262
|
+
const __filename2 = fileURLToPath3(import.meta.url);
|
|
54263
|
+
const __dirname4 = dirname6(__filename2);
|
|
54264
|
+
return resolve3(__dirname4, "..", "statusline", "writer.js");
|
|
54224
54265
|
}
|
|
54225
54266
|
}
|
|
54226
54267
|
|
|
54227
|
-
// src/version.ts
|
|
54228
|
-
import { readFileSync as readFileSync6, existsSync as existsSync8 } from "fs";
|
|
54229
|
-
import { dirname as dirname6, resolve as resolve3 } from "path";
|
|
54230
|
-
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
54231
|
-
var __dirname3 = dirname6(fileURLToPath3(import.meta.url));
|
|
54232
|
-
function loadPackageJson() {
|
|
54233
|
-
const candidates = [
|
|
54234
|
-
resolve3(__dirname3, "..", "package.json"),
|
|
54235
|
-
resolve3(__dirname3, "..", "..", "package.json"),
|
|
54236
|
-
resolve3(process.cwd(), "package.json")
|
|
54237
|
-
];
|
|
54238
|
-
for (const candidate of candidates) {
|
|
54239
|
-
if (existsSync8(candidate)) {
|
|
54240
|
-
try {
|
|
54241
|
-
const pkg = JSON.parse(readFileSync6(candidate, "utf-8"));
|
|
54242
|
-
if (pkg.name === "claude-threads") {
|
|
54243
|
-
return { version: pkg.version, name: pkg.name };
|
|
54244
|
-
}
|
|
54245
|
-
} catch {}
|
|
54246
|
-
}
|
|
54247
|
-
}
|
|
54248
|
-
return { version: "unknown", name: "claude-threads" };
|
|
54249
|
-
}
|
|
54250
|
-
var pkgInfo = loadPackageJson();
|
|
54251
|
-
var VERSION = pkgInfo.version;
|
|
54252
|
-
var PKG = pkgInfo;
|
|
54253
|
-
|
|
54254
54268
|
// src/commands/registry.ts
|
|
54255
54269
|
var COMMAND_REGISTRY = [
|
|
54256
54270
|
{
|
|
@@ -57260,7 +57274,7 @@ class TaskListExecutor extends BaseExecutor {
|
|
|
57260
57274
|
}
|
|
57261
57275
|
async withBumpQueue(fn) {
|
|
57262
57276
|
const prevQueue = this.bumpQueue;
|
|
57263
|
-
let releaseLock;
|
|
57277
|
+
let releaseLock = () => {};
|
|
57264
57278
|
this.bumpQueue = new Promise((resolve4) => {
|
|
57265
57279
|
releaseLock = resolve4;
|
|
57266
57280
|
});
|
|
@@ -60095,9 +60109,7 @@ async function buildStatusBar(sessionCount, config, formatter, platformId) {
|
|
|
60095
60109
|
items.push(formatter.formatCode(`⏸️ Update deferred`));
|
|
60096
60110
|
}
|
|
60097
60111
|
}
|
|
60098
|
-
|
|
60099
|
-
const versionStr = claudeVersion ? `v${VERSION} · CLI ${claudeVersion}` : `v${VERSION}`;
|
|
60100
|
-
items.push(formatter.formatCode(versionStr));
|
|
60112
|
+
items.push(formatter.formatCode(formatVersionString()));
|
|
60101
60113
|
items.push(formatter.formatCode(`${sessionCount}/${config.maxSessions} sessions`));
|
|
60102
60114
|
const permMode = config.skipPermissions ? "⚡ Auto" : "\uD83D\uDD10 Interactive";
|
|
60103
60115
|
items.push(formatter.formatCode(permMode));
|
|
@@ -60829,11 +60841,14 @@ class UsernameAnonymizer {
|
|
|
60829
60841
|
anonymize(username) {
|
|
60830
60842
|
if (!username)
|
|
60831
60843
|
return "[unknown]";
|
|
60832
|
-
|
|
60833
|
-
|
|
60834
|
-
|
|
60844
|
+
const existing = this.usernameMap.get(username);
|
|
60845
|
+
if (existing) {
|
|
60846
|
+
return existing;
|
|
60835
60847
|
}
|
|
60836
|
-
|
|
60848
|
+
this.counter++;
|
|
60849
|
+
const anonymized = `User${this.counter}`;
|
|
60850
|
+
this.usernameMap.set(username, anonymized);
|
|
60851
|
+
return anonymized;
|
|
60837
60852
|
}
|
|
60838
60853
|
}
|
|
60839
60854
|
function formatLogEntries(entries) {
|
|
@@ -64795,8 +64810,7 @@ async function updateSessionHeader(session, ctx) {
|
|
|
64795
64810
|
const permMode = isInteractive ? "\uD83D\uDD10 Interactive" : "⚡ Auto";
|
|
64796
64811
|
const otherParticipants = [...session.sessionAllowedUsers].filter((u) => u !== session.startedBy).map((u) => formatter.formatUserMention(u)).join(", ");
|
|
64797
64812
|
const statusItems = [];
|
|
64798
|
-
const
|
|
64799
|
-
const versionStr = claudeVersion ? `v${VERSION} · CLI ${claudeVersion}` : `v${VERSION}`;
|
|
64813
|
+
const versionStr = formatVersionString();
|
|
64800
64814
|
statusItems.push(formatter.formatCode(versionStr));
|
|
64801
64815
|
if (session.usageStats) {
|
|
64802
64816
|
const stats = session.usageStats;
|