@zhongqian97-code/ecode 0.5.24 → 0.5.26

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.
Files changed (2) hide show
  1. package/dist/index.js +40 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -108,6 +108,24 @@ function loadConfig() {
108
108
  defaultProvider: fileConfig.defaultProvider
109
109
  };
110
110
  }
111
+ function saveConfig(partial) {
112
+ const configPath = join(homedir(), ".ecode", "config.json");
113
+ const configDir = join(homedir(), ".ecode");
114
+ mkdirSync(configDir, { recursive: true });
115
+ let existing = {};
116
+ if (existsSync(configPath)) {
117
+ try {
118
+ const raw = readFileSync(configPath, "utf-8");
119
+ existing = JSON.parse(raw);
120
+ } catch (err) {
121
+ const msg = err instanceof Error ? err.message : String(err);
122
+ process.stderr.write(`[ecode] warning: ${configPath} parse failed (${msg}), overwriting with new config
123
+ `);
124
+ }
125
+ }
126
+ const merged = { ...existing, ...partial };
127
+ writeFileSync(configPath, JSON.stringify(merged, null, 2), "utf-8");
128
+ }
111
129
 
112
130
  // src/ui/App.tsx
113
131
  import { useState as useState3, useCallback, useRef as useRef2, useEffect as useEffect3, useMemo } from "react";
@@ -5744,7 +5762,11 @@ function generateAdminHtml(version2) {
5744
5762
  async function apiFetch(path, opts = {}) {
5745
5763
  const url = apiUrl(path);
5746
5764
  const res = await fetch(url, opts);
5747
- if (!res.ok) throw new Error(res.status + ' ' + res.statusText);
5765
+ if (!res.ok) {
5766
+ let msg = res.status + ' ' + res.statusText;
5767
+ try { const err = await res.json(); if (err.error) msg = err.error; } catch {}
5768
+ throw new Error(msg);
5769
+ }
5748
5770
  return res.json();
5749
5771
  }
5750
5772
 
@@ -6010,8 +6032,7 @@ function generateAdminHtml(version2) {
6010
6032
  } else if (type === 'session.error') {
6011
6033
  finalizeStreamingMsg();
6012
6034
  setStatus('idle');
6013
- document.getElementById('ws-status').textContent =
6014
- '\u9519\u8BEF: ' + escHtml(msg.error || 'unknown error');
6035
+ showToast('\u9519\u8BEF: ' + (msg.error || 'unknown error'), 'error');
6015
6036
  }
6016
6037
  }
6017
6038
 
@@ -6047,7 +6068,7 @@ function generateAdminHtml(version2) {
6047
6068
  body: JSON.stringify({ requestId: pending.requestId || pending.id, approved }),
6048
6069
  });
6049
6070
  } catch (e) {
6050
- document.getElementById('ws-status').textContent = '\u5BA1\u6279\u8BF7\u6C42\u5931\u8D25: ' + e.message;
6071
+ showToast('\u5BA1\u6279\u8BF7\u6C42\u5931\u8D25: ' + e.message, 'error');
6051
6072
  }
6052
6073
  }
6053
6074
 
@@ -6105,7 +6126,7 @@ function generateAdminHtml(version2) {
6105
6126
  body: JSON.stringify({ message: text }),
6106
6127
  });
6107
6128
  } catch (e) {
6108
- document.getElementById('ws-status').textContent = '\u53D1\u9001\u5931\u8D25: ' + e.message;
6129
+ showToast('\u53D1\u9001\u5931\u8D25: ' + e.message, 'error');
6109
6130
  setStatus('idle');
6110
6131
  }
6111
6132
  }
@@ -6484,8 +6505,19 @@ async function chatRoutes(app, opts) {
6484
6505
  if (typeof body.systemPrompt === "string") {
6485
6506
  sessionOpts.systemPrompt = body.systemPrompt;
6486
6507
  }
6487
- const runtime = await manager.createSession(sessionOpts);
6488
- return reply.code(201).send({ success: true, session: runtime.snapshot() });
6508
+ if (!opts.config.apiKey) {
6509
+ return reply.code(400).send({
6510
+ success: false,
6511
+ error: "\u672A\u914D\u7F6E API Key\uFF0C\u8BF7\u5148\u70B9\u51FB\u53F3\u4E0A\u89D2\u300C\u914D\u7F6E\u300D\u6309\u94AE\u586B\u5199"
6512
+ });
6513
+ }
6514
+ try {
6515
+ const runtime = await manager.createSession(sessionOpts);
6516
+ return reply.code(201).send({ success: true, session: runtime.snapshot() });
6517
+ } catch (err) {
6518
+ const msg = err instanceof Error ? err.message : String(err);
6519
+ return reply.code(500).send({ success: false, error: msg });
6520
+ }
6489
6521
  });
6490
6522
  app.post("/api/chat/sessions/:id/submit", async (request, reply) => {
6491
6523
  const { id } = request.params;
@@ -6630,7 +6662,7 @@ async function buildServer(opts) {
6630
6662
  version: opts.version
6631
6663
  });
6632
6664
  await app.register(sessionsRoutes, { config: opts.config, manager: opts.manager });
6633
- await app.register(configRoutes, { config: opts.config });
6665
+ await app.register(configRoutes, { config: opts.config, save: saveConfig });
6634
6666
  await app.register(automationRoutes, { config: opts.config });
6635
6667
  await app.register(chatRoutes, { config: opts.config, manager: opts.manager });
6636
6668
  await app.register(systemRoutes, { version: opts.version });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhongqian97-code/ecode",
3
- "version": "0.5.24",
3
+ "version": "0.5.26",
4
4
  "description": "A minimal Claude Code clone with REPL interface and bash tool calling",
5
5
  "type": "module",
6
6
  "author": "zhongqian97-code",