claude-b 0.3.3 → 0.4.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.
@@ -24,11 +24,6 @@ import { nanoid } from "nanoid";
24
24
  import { EventEmitter } from "events";
25
25
  import { mkdir, writeFile, readFile, appendFile } from "fs/promises";
26
26
  import { existsSync } from "fs";
27
- var pty = null;
28
- try {
29
- pty = await import("node-pty");
30
- } catch {
31
- }
32
27
  var Session = class _Session extends EventEmitter {
33
28
  id;
34
29
  name;
@@ -39,7 +34,6 @@ var Session = class _Session extends EventEmitter {
39
34
  fireAndForget = false;
40
35
  lastActivityAt;
41
36
  workingDir;
42
- configDir;
43
37
  sessionDir;
44
38
  process = null;
45
39
  outputBuffer = [];
@@ -64,7 +58,6 @@ var Session = class _Session extends EventEmitter {
64
58
  this.status = state.status;
65
59
  this.createdAt = state.createdAt;
66
60
  this.workingDir = state.workingDir;
67
- this.configDir = configDir;
68
61
  this.sessionDir = `${configDir}/sessions/${this.id}`;
69
62
  this.lastPromptId = state.lastPromptId;
70
63
  this.promptCount = state.promptCount || 0;
@@ -154,14 +147,6 @@ var Session = class _Session extends EventEmitter {
154
147
  const historyPath = `${this.sessionDir}/history.jsonl`;
155
148
  await appendFile(historyPath, JSON.stringify(entry) + "\n");
156
149
  }
157
- waitForReady() {
158
- if (this.isReady) {
159
- return Promise.resolve();
160
- }
161
- return new Promise((resolve) => {
162
- this.readyResolvers.push(resolve);
163
- });
164
- }
165
150
  markReady() {
166
151
  if (this.isReady) return;
167
152
  this.isReady = true;
@@ -170,47 +155,6 @@ var Session = class _Session extends EventEmitter {
170
155
  }
171
156
  this.readyResolvers = [];
172
157
  }
173
- async startClaudeProcess() {
174
- if (this.process) {
175
- return;
176
- }
177
- await this.ensureSessionDir();
178
- const claudePath = getClaudePath();
179
- if (pty) {
180
- this.process = pty.spawn(claudePath, ["--dangerously-skip-permissions"], {
181
- name: "xterm-256color",
182
- cols: 120,
183
- rows: 40,
184
- cwd: this.workingDir,
185
- env: { ...process.env, TERM: "xterm-256color" }
186
- });
187
- this.process.onData((data) => {
188
- this.handleOutput(data);
189
- });
190
- this.process.onExit(({ exitCode }) => {
191
- this.handleProcessExit(exitCode);
192
- });
193
- } else {
194
- const proc = spawn(claudePath, ["--print"], {
195
- cwd: this.workingDir,
196
- stdio: ["pipe", "pipe", "pipe"],
197
- env: { ...process.env }
198
- });
199
- this.process = proc;
200
- proc.stdout?.on("data", (chunk) => {
201
- this.handleOutput(chunk.toString());
202
- });
203
- proc.stderr?.on("data", (chunk) => {
204
- this.handleOutput(chunk.toString());
205
- });
206
- proc.on("exit", (code) => {
207
- this.handleProcessExit(code);
208
- });
209
- proc.on("error", (error) => {
210
- this.handleProcessError(error);
211
- });
212
- }
213
- }
214
158
  handleOutput(data) {
215
159
  this.outputBuffer.push(data);
216
160
  this.currentPromptOutput.push(data);
@@ -969,7 +913,7 @@ async function registerSessionRoutes(app, sessionManager) {
969
913
  });
970
914
  app.get("/api/sessions/current", {
971
915
  preHandler: [app.authenticate]
972
- }, async (request, reply) => {
916
+ }, async (_request, reply) => {
973
917
  const session = sessionManager.current();
974
918
  if (!session) {
975
919
  return reply.status(404).send({
@@ -1131,7 +1075,7 @@ async function registerAuthRoutes(app, authManager) {
1131
1075
  });
1132
1076
  app.get("/api/auth/verify", {
1133
1077
  preHandler: [app.authenticate]
1134
- }, async (request, reply) => {
1078
+ }, async (request, _reply) => {
1135
1079
  return {
1136
1080
  valid: true,
1137
1081
  user: request.user
@@ -1504,13 +1448,16 @@ var RemoteClient = class extends EventEmitter2 {
1504
1448
  const timeoutId = setTimeout(() => controller.abort(), timeout);
1505
1449
  try {
1506
1450
  const start = Date.now();
1451
+ const headers = {
1452
+ "Authorization": `Bearer ${token}`
1453
+ };
1454
+ if (body !== void 0) {
1455
+ headers["Content-Type"] = "application/json";
1456
+ }
1507
1457
  const response = await fetch(`${this.host.url}${path}`, {
1508
1458
  method,
1509
- headers: {
1510
- "Authorization": `Bearer ${token}`,
1511
- "Content-Type": "application/json"
1512
- },
1513
- body: body ? JSON.stringify(body) : void 0,
1459
+ headers,
1460
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
1514
1461
  signal: controller.signal
1515
1462
  });
1516
1463
  const latency = Date.now() - start;
@@ -1555,9 +1502,9 @@ var RemoteClient = class extends EventEmitter2 {
1555
1502
  const result = await this.request(
1556
1503
  "POST",
1557
1504
  "/api/sessions",
1558
- name ? { name } : void 0
1505
+ name ? { name } : {}
1559
1506
  );
1560
- return { ...result.session, host: this.host.id };
1507
+ return { ...result, host: this.host.id };
1561
1508
  }
1562
1509
  async getSession(sessionId) {
1563
1510
  try {
@@ -1565,7 +1512,7 @@ var RemoteClient = class extends EventEmitter2 {
1565
1512
  "GET",
1566
1513
  `/api/sessions/${sessionId}`
1567
1514
  );
1568
- return { ...result.session, host: this.host.id };
1515
+ return { ...result, host: this.host.id };
1569
1516
  } catch {
1570
1517
  return null;
1571
1518
  }
@@ -1859,7 +1806,7 @@ var PipelineExecutor = class extends EventEmitter3 {
1859
1806
  results = await Promise.race([
1860
1807
  Promise.all(promises),
1861
1808
  new Promise((resolve) => {
1862
- promises.forEach(async (p, i) => {
1809
+ promises.forEach(async (p) => {
1863
1810
  const result = await p;
1864
1811
  if (result.status === "completed") {
1865
1812
  resolve([result]);
@@ -2029,12 +1976,10 @@ var HealthMonitor = class extends EventEmitter4 {
2029
1976
  isHealthy = true;
2030
1977
  consecutiveFailures = 0;
2031
1978
  consecutiveSuccesses = 0;
2032
- startTime;
2033
1979
  constructor(client, config) {
2034
1980
  super();
2035
1981
  this.client = client;
2036
1982
  this.config = { ...DEFAULT_CONFIG, ...config };
2037
- this.startTime = Date.now();
2038
1983
  }
2039
1984
  start() {
2040
1985
  if (this.intervalId) return;
@@ -2808,6 +2753,7 @@ var OrchestrationManager = class extends EventEmitter6 {
2808
2753
  }
2809
2754
  };
2810
2755
  function createHost(url, apiKey, options) {
2756
+ const hc = options?.healthCheck;
2811
2757
  return {
2812
2758
  id: nanoid2(8),
2813
2759
  name: options?.name || new URL(url).hostname,
@@ -2816,7 +2762,11 @@ function createHost(url, apiKey, options) {
2816
2762
  apiKey,
2817
2763
  enabled: options?.enabled ?? true,
2818
2764
  priority: options?.priority ?? 1,
2819
- healthCheck: options?.healthCheck
2765
+ healthCheck: hc ? {
2766
+ interval: hc.interval ?? 3e4,
2767
+ timeout: hc.timeout ?? 5e3,
2768
+ unhealthyThreshold: hc.unhealthyThreshold ?? 3
2769
+ } : void 0
2820
2770
  };
2821
2771
  }
2822
2772
 
@@ -3666,6 +3616,17 @@ var NotificationInbox = class {
3666
3616
  // src/telegram/bot.ts
3667
3617
  import TelegramBot from "node-telegram-bot-api";
3668
3618
  import { EventEmitter as EventEmitter8 } from "events";
3619
+
3620
+ // src/telegram/allow-list.ts
3621
+ function isChatAllowed(chatId, allowedRaw) {
3622
+ const raw = allowedRaw?.trim();
3623
+ if (!raw) return true;
3624
+ const allowed = raw.split(",").map((s) => s.trim()).filter(Boolean);
3625
+ if (allowed.length === 0) return true;
3626
+ return allowed.includes(chatId);
3627
+ }
3628
+
3629
+ // src/telegram/bot.ts
3669
3630
  function markdownToTelegramHtml(md) {
3670
3631
  const codeBlocks = [];
3671
3632
  let html = md.replace(/```[\w]*\n?([\s\S]*?)```/g, (_m, code) => {
@@ -3872,13 +3833,9 @@ var ClaudeBTelegramBot = class extends EventEmitter8 {
3872
3833
  }
3873
3834
  async handleStart(msg) {
3874
3835
  const chatId = String(msg.chat.id);
3875
- const allowedRaw = process.env.TELEGRAM_ALLOWED_CHAT_IDS?.trim();
3876
- if (allowedRaw) {
3877
- const allowed = allowedRaw.split(",").map((s) => s.trim()).filter(Boolean);
3878
- if (allowed.length > 0 && !allowed.includes(chatId)) {
3879
- await this.safeSend(chatId, "\u26D4 This bot is private. Your chat is not authorised.");
3880
- return;
3881
- }
3836
+ if (!isChatAllowed(chatId, process.env.TELEGRAM_ALLOWED_CHAT_IDS)) {
3837
+ await this.safeSend(chatId, "\u26D4 This bot is private. Your chat is not authorised.");
3838
+ return;
3882
3839
  }
3883
3840
  await this.configManager.addChatId(chatId);
3884
3841
  const voiceStatus = this.voicePipeline ? "\u{1F3A4} Voice input: Active" : "\u{1F3A4} Voice input: Not configured";
@@ -4485,7 +4442,7 @@ function createSTTTTSProvider(config, tempDir) {
4485
4442
  case "deepgram":
4486
4443
  return new DeepgramProvider(config.apiKey);
4487
4444
  case "openai":
4488
- return new OpenAIProvider(config.apiKey, tempDir, config.ttsModel, config.ttsVoice);
4445
+ return new OpenAIProvider(config.apiKey, config.ttsModel, config.ttsVoice);
4489
4446
  default:
4490
4447
  throw new Error(`Unknown STT provider: ${config.provider}`);
4491
4448
  }
@@ -4583,12 +4540,10 @@ var DeepgramProvider = class {
4583
4540
  };
4584
4541
  var OpenAIProvider = class {
4585
4542
  apiKey;
4586
- tempDir;
4587
4543
  ttsModel;
4588
4544
  ttsVoice;
4589
- constructor(apiKey, tempDir, ttsModel, ttsVoice) {
4545
+ constructor(apiKey, ttsModel, ttsVoice) {
4590
4546
  this.apiKey = apiKey;
4591
- this.tempDir = tempDir;
4592
4547
  this.ttsModel = ttsModel || "gpt-4o-mini-tts";
4593
4548
  this.ttsVoice = ttsVoice || "alloy";
4594
4549
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-b",
3
- "version": "0.3.3",
3
+ "version": "0.4.1",
4
4
  "description": "Background-capable Claude Code with async workflows and REST API",
5
5
  "type": "module",
6
6
  "main": "dist/cli/index.js",