episoda 0.2.48 → 0.2.50

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.
@@ -2277,21 +2277,36 @@ var require_websocket_client = __commonJS({
2277
2277
  }
2278
2278
  }
2279
2279
  }
2280
+ /**
2281
+ * EP1034: Remove all event handlers
2282
+ * Useful when completely resetting a client or when the daemon
2283
+ * disconnects a project and creates a fresh connection.
2284
+ * Note: Internal reconnection (scheduleReconnect) uses the same client instance,
2285
+ * so handlers persist across reconnects - this is by design.
2286
+ */
2287
+ clearAllHandlers() {
2288
+ this.eventHandlers.clear();
2289
+ }
2280
2290
  /**
2281
2291
  * Send a message to the server
2282
2292
  * @param message - Client message to send
2293
+ * @returns true if message was sent, false if not connected
2294
+ *
2295
+ * EP1034: Changed to return false instead of throwing when disconnected.
2296
+ * This prevents daemon crashes when async operations complete during reconnection.
2283
2297
  */
2284
2298
  async send(message) {
2285
2299
  if (!this.ws || !this.isConnected) {
2286
- throw new Error("WebSocket not connected");
2300
+ console.warn("[EpisodaClient] Cannot send - WebSocket not connected");
2301
+ return false;
2287
2302
  }
2288
- return new Promise((resolve3, reject) => {
2303
+ return new Promise((resolve3) => {
2289
2304
  this.ws.send(JSON.stringify(message), (error) => {
2290
2305
  if (error) {
2291
2306
  console.error("[EpisodaClient] Failed to send message:", error);
2292
- reject(error);
2307
+ resolve3(false);
2293
2308
  } else {
2294
- resolve3();
2309
+ resolve3(true);
2295
2310
  }
2296
2311
  });
2297
2312
  });
@@ -2559,17 +2574,27 @@ var require_auth = __commonJS({
2559
2574
  }
2560
2575
  async function loadConfig7(configPath) {
2561
2576
  const fullPath = getConfigPath(configPath);
2562
- if (!fs18.existsSync(fullPath)) {
2563
- return null;
2577
+ if (fs18.existsSync(fullPath)) {
2578
+ try {
2579
+ const content = fs18.readFileSync(fullPath, "utf8");
2580
+ const config = JSON.parse(content);
2581
+ return config;
2582
+ } catch (error) {
2583
+ console.error("Error loading config:", error);
2584
+ }
2564
2585
  }
2565
- try {
2566
- const content = fs18.readFileSync(fullPath, "utf8");
2567
- const config = JSON.parse(content);
2568
- return config;
2569
- } catch (error) {
2570
- console.error("Error loading config:", error);
2571
- return null;
2586
+ if (process.env.EPISODA_ACCESS_TOKEN) {
2587
+ return {
2588
+ access_token: process.env.EPISODA_ACCESS_TOKEN,
2589
+ api_url: process.env.EPISODA_API_URL || "https://episoda.dev",
2590
+ project_id: process.env.EPISODA_PROJECT_ID || "",
2591
+ user_id: process.env.EPISODA_USER_ID || "",
2592
+ workspace_id: process.env.EPISODA_WORKSPACE_ID || "",
2593
+ workspace_slug: process.env.EPISODA_WORKSPACE,
2594
+ project_slug: process.env.EPISODA_PROJECT
2595
+ };
2572
2596
  }
2597
+ return null;
2573
2598
  }
2574
2599
  async function saveConfig2(config, configPath) {
2575
2600
  const fullPath = getConfigPath(configPath);
@@ -2693,7 +2718,7 @@ var require_package = __commonJS({
2693
2718
  "package.json"(exports2, module2) {
2694
2719
  module2.exports = {
2695
2720
  name: "episoda",
2696
- version: "0.2.48",
2721
+ version: "0.2.50",
2697
2722
  description: "CLI tool for Episoda local development workflow orchestration",
2698
2723
  main: "dist/index.js",
2699
2724
  types: "dist/index.d.ts",
@@ -2702,6 +2727,7 @@ var require_package = __commonJS({
2702
2727
  },
2703
2728
  scripts: {
2704
2729
  build: "tsup",
2730
+ "build:standalone": "tsup --config tsup.standalone.config.ts",
2705
2731
  dev: "tsup --watch",
2706
2732
  clean: "rm -rf dist",
2707
2733
  typecheck: "tsc --noEmit"