claude-threads 1.6.3 → 1.7.0
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 +7 -0
- package/dist/index.js +576 -309
- package/dist/mcp/permission-server.js +137 -37
- package/package.json +1 -1
|
@@ -53500,6 +53500,64 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
53500
53500
|
import { existsSync as existsSync4, readFileSync as readFileSync3, watchFile, unwatchFile, unlinkSync, statSync, readdirSync } from "fs";
|
|
53501
53501
|
import { tmpdir } from "os";
|
|
53502
53502
|
import { join as join3 } from "path";
|
|
53503
|
+
|
|
53504
|
+
// src/claude/rate-limit-detector.ts
|
|
53505
|
+
var RATE_LIMIT_PHRASES = [
|
|
53506
|
+
/usage limit reached/i,
|
|
53507
|
+
/rate[_\s-]?limit[_\s-]?error/i,
|
|
53508
|
+
/you have hit the rate limit/i,
|
|
53509
|
+
/quota (has been )?exceeded/i,
|
|
53510
|
+
/\b429\b.*(rate|limit|quota)/i
|
|
53511
|
+
];
|
|
53512
|
+
var DEFAULT_COOLDOWN_MS = 60 * 60 * 1000;
|
|
53513
|
+
function detectRateLimit(text, now = Date.now()) {
|
|
53514
|
+
if (!text)
|
|
53515
|
+
return { detected: false };
|
|
53516
|
+
let matched;
|
|
53517
|
+
for (const phrase of RATE_LIMIT_PHRASES) {
|
|
53518
|
+
const m = text.match(phrase);
|
|
53519
|
+
if (m) {
|
|
53520
|
+
matched = m[0];
|
|
53521
|
+
break;
|
|
53522
|
+
}
|
|
53523
|
+
}
|
|
53524
|
+
if (!matched)
|
|
53525
|
+
return { detected: false };
|
|
53526
|
+
const resetAtEpochMs = extractResetAt(text, now);
|
|
53527
|
+
return { detected: true, matched, resetAtEpochMs };
|
|
53528
|
+
}
|
|
53529
|
+
function extractResetAt(text, now) {
|
|
53530
|
+
const relative = text.match(/(?:retry[_\s-]?after|resets?\s+in)\s+(\d+)\s*(second|minute|hour|day)s?/i);
|
|
53531
|
+
if (relative) {
|
|
53532
|
+
const value = parseInt(relative[1], 10);
|
|
53533
|
+
const unit = relative[2].toLowerCase();
|
|
53534
|
+
const unitMs = {
|
|
53535
|
+
second: 1000,
|
|
53536
|
+
minute: 60000,
|
|
53537
|
+
hour: 3600000,
|
|
53538
|
+
day: 86400000
|
|
53539
|
+
};
|
|
53540
|
+
return now + value * unitMs[unit];
|
|
53541
|
+
}
|
|
53542
|
+
const unix = text.match(/["']?reset(?:_at)?["']?\s*[:=]\s*(\d{10,13})/);
|
|
53543
|
+
if (unix) {
|
|
53544
|
+
const raw = parseInt(unix[1], 10);
|
|
53545
|
+
return unix[1].length === 13 ? raw : raw * 1000;
|
|
53546
|
+
}
|
|
53547
|
+
const clock = text.match(/resets?\s+at\s+(\d{1,2}):(\d{2})\s*(utc|gmt)?/i);
|
|
53548
|
+
if (clock) {
|
|
53549
|
+
const hh = parseInt(clock[1], 10);
|
|
53550
|
+
const mm = parseInt(clock[2], 10);
|
|
53551
|
+
if (hh < 24 && mm < 60) {
|
|
53552
|
+
const reference = new Date(now);
|
|
53553
|
+
const target = new Date(Date.UTC(reference.getUTCFullYear(), reference.getUTCMonth(), reference.getUTCDate(), hh, mm)).getTime();
|
|
53554
|
+
return target > now ? target : target + 86400000;
|
|
53555
|
+
}
|
|
53556
|
+
}
|
|
53557
|
+
return;
|
|
53558
|
+
}
|
|
53559
|
+
|
|
53560
|
+
// src/claude/cli.ts
|
|
53503
53561
|
var log7 = createLogger("claude");
|
|
53504
53562
|
function cleanupBrowserBridgeSockets() {
|
|
53505
53563
|
try {
|
|
@@ -53521,6 +53579,14 @@ function cleanupBrowserBridgeSockets() {
|
|
|
53521
53579
|
log7.debug(`Browser bridge cleanup failed: ${err}`);
|
|
53522
53580
|
}
|
|
53523
53581
|
}
|
|
53582
|
+
function isErrorResultEvent(event) {
|
|
53583
|
+
const ev = event;
|
|
53584
|
+
if (typeof ev.subtype === "string" && ev.subtype.startsWith("error"))
|
|
53585
|
+
return true;
|
|
53586
|
+
if (ev.is_error === true)
|
|
53587
|
+
return true;
|
|
53588
|
+
return false;
|
|
53589
|
+
}
|
|
53524
53590
|
|
|
53525
53591
|
class ClaudeCli extends EventEmitter2 {
|
|
53526
53592
|
process = null;
|
|
@@ -53530,6 +53596,7 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53530
53596
|
statusFilePath = null;
|
|
53531
53597
|
lastStatusData = null;
|
|
53532
53598
|
stderrBuffer = "";
|
|
53599
|
+
rateLimitEmitted = false;
|
|
53533
53600
|
log;
|
|
53534
53601
|
constructor(options2) {
|
|
53535
53602
|
super();
|
|
@@ -53581,6 +53648,7 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53581
53648
|
if (this.process)
|
|
53582
53649
|
throw new Error("Already running");
|
|
53583
53650
|
this.stderrBuffer = "";
|
|
53651
|
+
this.rateLimitEmitted = false;
|
|
53584
53652
|
cleanupBrowserBridgeSockets();
|
|
53585
53653
|
const claudePath = getClaudePath();
|
|
53586
53654
|
const args = [
|
|
@@ -53650,9 +53718,13 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53650
53718
|
args.push("--settings", JSON.stringify(statusLineSettings));
|
|
53651
53719
|
}
|
|
53652
53720
|
this.log.debug(`Starting: ${claudePath} ${args.slice(0, 5).join(" ")}...`);
|
|
53721
|
+
const childEnv = this.buildChildEnv();
|
|
53722
|
+
if (this.options.account) {
|
|
53723
|
+
this.log.debug(`Spawning under Claude account "${this.options.account.id}"`);
|
|
53724
|
+
}
|
|
53653
53725
|
this.process = crossSpawn(claudePath, args, {
|
|
53654
53726
|
cwd: this.options.workingDir,
|
|
53655
|
-
env:
|
|
53727
|
+
env: childEnv,
|
|
53656
53728
|
stdio: ["pipe", "pipe", "pipe"]
|
|
53657
53729
|
});
|
|
53658
53730
|
this.log.debug(`Claude process spawned: pid=${this.process.pid}`);
|
|
@@ -53666,6 +53738,7 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53666
53738
|
this.stderrBuffer = this.stderrBuffer.slice(-10240);
|
|
53667
53739
|
}
|
|
53668
53740
|
this.log.debug(`stderr: ${text.trim()}`);
|
|
53741
|
+
this.maybeEmitRateLimit(text);
|
|
53669
53742
|
});
|
|
53670
53743
|
this.process.on("error", (err) => {
|
|
53671
53744
|
this.log.error(`Claude error: ${err}`);
|
|
@@ -53720,9 +53793,22 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53720
53793
|
try {
|
|
53721
53794
|
const event = JSON.parse(trimmed);
|
|
53722
53795
|
this.emit("event", event);
|
|
53796
|
+
if (event.type === "result" && isErrorResultEvent(event)) {
|
|
53797
|
+
this.maybeEmitRateLimit(trimmed);
|
|
53798
|
+
}
|
|
53723
53799
|
} catch {}
|
|
53724
53800
|
}
|
|
53725
53801
|
}
|
|
53802
|
+
maybeEmitRateLimit(text) {
|
|
53803
|
+
const hit = detectRateLimit(text);
|
|
53804
|
+
if (!hit.detected)
|
|
53805
|
+
return;
|
|
53806
|
+
if (this.rateLimitEmitted)
|
|
53807
|
+
return;
|
|
53808
|
+
this.rateLimitEmitted = true;
|
|
53809
|
+
this.log.warn(`Rate limit detected: ${hit.matched ?? "(no match text)"}`);
|
|
53810
|
+
this.emit("rate-limit", hit);
|
|
53811
|
+
}
|
|
53726
53812
|
isRunning() {
|
|
53727
53813
|
return this.process !== null;
|
|
53728
53814
|
}
|
|
@@ -53791,6 +53877,22 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53791
53877
|
this.process.kill("SIGINT");
|
|
53792
53878
|
return true;
|
|
53793
53879
|
}
|
|
53880
|
+
buildChildEnv() {
|
|
53881
|
+
const account = this.options.account;
|
|
53882
|
+
if (!account)
|
|
53883
|
+
return process.env;
|
|
53884
|
+
const env = { ...process.env };
|
|
53885
|
+
if (account.home) {
|
|
53886
|
+
env.HOME = account.home;
|
|
53887
|
+
env.USERPROFILE = account.home;
|
|
53888
|
+
delete env.ANTHROPIC_API_KEY;
|
|
53889
|
+
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
53890
|
+
} else if (account.apiKey) {
|
|
53891
|
+
env.ANTHROPIC_API_KEY = account.apiKey;
|
|
53892
|
+
delete env.CLAUDE_CODE_OAUTH_TOKEN;
|
|
53893
|
+
}
|
|
53894
|
+
return env;
|
|
53895
|
+
}
|
|
53794
53896
|
getMcpServerPath() {
|
|
53795
53897
|
const __filename2 = fileURLToPath3(import.meta.url);
|
|
53796
53898
|
const __dirname4 = dirname4(__filename2);
|
|
@@ -53811,42 +53913,6 @@ class ClaudeCli extends EventEmitter2 {
|
|
|
53811
53913
|
}
|
|
53812
53914
|
}
|
|
53813
53915
|
|
|
53814
|
-
// src/update-notifier.ts
|
|
53815
|
-
var import_semver2 = __toESM(require_semver2(), 1);
|
|
53816
|
-
|
|
53817
|
-
// src/operations/commands/handler.ts
|
|
53818
|
-
init_emoji();
|
|
53819
|
-
|
|
53820
|
-
// src/utils/error-handler/index.ts
|
|
53821
|
-
var log8 = createLogger("error");
|
|
53822
|
-
|
|
53823
|
-
// src/utils/session-log.ts
|
|
53824
|
-
function createSessionLog(baseLog) {
|
|
53825
|
-
return (session) => {
|
|
53826
|
-
if (session?.sessionId) {
|
|
53827
|
-
return baseLog.forSession(session.sessionId);
|
|
53828
|
-
}
|
|
53829
|
-
return baseLog;
|
|
53830
|
-
};
|
|
53831
|
-
}
|
|
53832
|
-
|
|
53833
|
-
// src/operations/post-helpers/index.ts
|
|
53834
|
-
init_emoji();
|
|
53835
|
-
|
|
53836
|
-
// src/git/worktree.ts
|
|
53837
|
-
import * as path from "path";
|
|
53838
|
-
import { homedir as homedir2 } from "os";
|
|
53839
|
-
var log9 = createLogger("git-wt");
|
|
53840
|
-
var WORKTREES_DIR = path.join(homedir2(), ".claude-threads", "worktrees");
|
|
53841
|
-
var METADATA_STORE_PATH = path.join(homedir2(), ".claude-threads", "worktree-metadata.json");
|
|
53842
|
-
|
|
53843
|
-
// src/operations/post-helpers/index.ts
|
|
53844
|
-
var log10 = createLogger("helpers");
|
|
53845
|
-
var sessionLog = createSessionLog(log10);
|
|
53846
|
-
|
|
53847
|
-
// src/claude/quick-query.ts
|
|
53848
|
-
var log11 = createLogger("query");
|
|
53849
|
-
|
|
53850
53916
|
// src/commands/registry.ts
|
|
53851
53917
|
var COMMAND_REGISTRY = [
|
|
53852
53918
|
{
|
|
@@ -54399,6 +54465,36 @@ ${avoidCommands.map((c) => `- \`!${c.command}\` - ${c.reason}`).join(`
|
|
|
54399
54465
|
`)}
|
|
54400
54466
|
`.trim();
|
|
54401
54467
|
}
|
|
54468
|
+
// src/utils/error-handler/index.ts
|
|
54469
|
+
var log8 = createLogger("error");
|
|
54470
|
+
|
|
54471
|
+
// src/utils/session-log.ts
|
|
54472
|
+
function createSessionLog(baseLog) {
|
|
54473
|
+
return (session) => {
|
|
54474
|
+
if (session?.sessionId) {
|
|
54475
|
+
return baseLog.forSession(session.sessionId);
|
|
54476
|
+
}
|
|
54477
|
+
return baseLog;
|
|
54478
|
+
};
|
|
54479
|
+
}
|
|
54480
|
+
|
|
54481
|
+
// src/operations/post-helpers/index.ts
|
|
54482
|
+
init_emoji();
|
|
54483
|
+
|
|
54484
|
+
// src/git/worktree.ts
|
|
54485
|
+
import * as path from "path";
|
|
54486
|
+
import { homedir as homedir2 } from "os";
|
|
54487
|
+
var log9 = createLogger("git-wt");
|
|
54488
|
+
var WORKTREES_DIR = path.join(homedir2(), ".claude-threads", "worktrees");
|
|
54489
|
+
var METADATA_STORE_PATH = path.join(homedir2(), ".claude-threads", "worktree-metadata.json");
|
|
54490
|
+
|
|
54491
|
+
// src/operations/post-helpers/index.ts
|
|
54492
|
+
var log10 = createLogger("helpers");
|
|
54493
|
+
var sessionLog = createSessionLog(log10);
|
|
54494
|
+
|
|
54495
|
+
// src/claude/quick-query.ts
|
|
54496
|
+
var log11 = createLogger("query");
|
|
54497
|
+
|
|
54402
54498
|
// src/operations/suggestions/title.ts
|
|
54403
54499
|
var log12 = createLogger("title");
|
|
54404
54500
|
|
|
@@ -54416,7 +54512,11 @@ var log15 = createLogger("lifecycle");
|
|
|
54416
54512
|
var sessionLog3 = createSessionLog(log15);
|
|
54417
54513
|
var CHAT_PLATFORM_PROMPT = generateChatPlatformPrompt();
|
|
54418
54514
|
|
|
54515
|
+
// src/update-notifier.ts
|
|
54516
|
+
var import_semver2 = __toESM(require_semver2(), 1);
|
|
54517
|
+
|
|
54419
54518
|
// src/operations/commands/handler.ts
|
|
54519
|
+
init_emoji();
|
|
54420
54520
|
var log16 = createLogger("commands");
|
|
54421
54521
|
var sessionLog4 = createSessionLog(log16);
|
|
54422
54522
|
// src/operations/suggestions/branch.ts
|