apex-dev 3.10.19 → 3.10.20

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 (3) hide show
  1. package/cli.js +72 -35
  2. package/dist/index.js +14 -5
  3. package/package.json +1 -1
package/cli.js CHANGED
@@ -145,6 +145,8 @@ function getDownloadUrl() {
145
145
  return `https://github.com/Marcus-Mok-GH/apex-dev/releases/download/v${VERSION}/apex-dev-${platform}-${arch}`;
146
146
  }
147
147
 
148
+ const DOWNLOAD_TIMEOUT = 10 * 1000;
149
+
148
150
  function downloadBinary(destPath) {
149
151
  const url = getDownloadUrl();
150
152
  console.error(`Downloading apex-dev v${VERSION} for ${detectPlatform().platform}-${detectPlatform().arch}...`);
@@ -152,45 +154,80 @@ function downloadBinary(destPath) {
152
154
 
153
155
  return new Promise((resolve, reject) => {
154
156
  const file = fs.createWriteStream(destPath, { mode: 0o755 });
155
- const DOWNLOAD_TIMEOUT = 10000;
156
-
157
- const req = https
158
- .get(url, { timeout: DOWNLOAD_TIMEOUT }, (response) => {
159
- if (response.statusCode === 302 || response.statusCode === 301) {
160
- const redirectReq = https.get(response.headers.location, { timeout: DOWNLOAD_TIMEOUT }, (redirectRes) => {
161
- if (redirectRes.statusCode !== 200) {
162
- reject(new Error(`Download failed with status ${redirectRes.statusCode}`));
163
- return;
164
- }
165
- redirectRes.pipe(file);
166
- file.on("finish", () => {
167
- file.close();
168
- resolve();
169
- });
170
- });
171
- redirectReq.on("error", reject);
172
- redirectReq.on("timeout", () => {
173
- redirectReq.destroy();
174
- reject(new Error("Download timed out after 10s"));
175
- });
176
- return;
157
+ let settled = false;
158
+
159
+ function cleanupAndReject(err) {
160
+ if (settled) return;
161
+ settled = true;
162
+ file.destroy();
163
+ try { fs.unlinkSync(destPath); } catch {}
164
+ reject(err);
165
+ }
166
+
167
+ function onFileError(err) {
168
+ cleanupAndReject(new Error(`Write stream error: ${err.message}`));
169
+ }
170
+
171
+ file.on("error", onFileError);
172
+
173
+ const req = https.get(url, (response) => {
174
+ if (response.statusCode === 302 || response.statusCode === 301) {
175
+ const redirectReq = https.get(response.headers.location, (redirectRes) => {
176
+ if (redirectRes.statusCode !== 200) {
177
+ cleanupAndReject(new Error(`Download failed with status ${redirectRes.statusCode}`));
178
+ return;
179
+ }
180
+
181
+ function onFinish() {
182
+ file.removeListener("error", onFileError);
183
+ redirectReq.removeListener("error", onRedirectError);
184
+ redirectReq.removeListener("timeout", onRedirectTimeout);
185
+ file.close();
186
+ resolve();
187
+ }
188
+
189
+ file.on("finish", onFinish);
190
+ redirectRes.pipe(file);
191
+ });
192
+
193
+ function onRedirectError(err) {
194
+ cleanupAndReject(new Error(`Redirect request error: ${err.message}`));
177
195
  }
178
- if (response.statusCode !== 200) {
179
- reject(new Error(`Download failed with status ${response.statusCode}`));
180
- return;
196
+ function onRedirectTimeout() {
197
+ cleanupAndReject(new Error("Download redirect timed out"));
181
198
  }
182
- response.pipe(file);
183
- file.on("finish", () => {
184
- file.close();
185
- resolve();
186
- });
187
- });
188
199
 
189
- req.on("error", reject);
190
- req.on("timeout", () => {
191
- req.destroy();
192
- reject(new Error("Download timed out after 10s"));
200
+ redirectReq.on("error", onRedirectError);
201
+ redirectReq.setTimeout(DOWNLOAD_TIMEOUT, onRedirectTimeout);
202
+ return;
203
+ }
204
+
205
+ if (response.statusCode !== 200) {
206
+ cleanupAndReject(new Error(`Download failed with status ${response.statusCode}`));
207
+ return;
208
+ }
209
+
210
+ function onFinish() {
211
+ file.removeListener("error", onFileError);
212
+ req.removeListener("error", onReqError);
213
+ req.removeListener("timeout", onReqTimeout);
214
+ file.close();
215
+ resolve();
216
+ }
217
+
218
+ file.on("finish", onFinish);
219
+ response.pipe(file);
193
220
  });
221
+
222
+ function onReqError(err) {
223
+ cleanupAndReject(new Error(`Download request error: ${err.message}`));
224
+ }
225
+ function onReqTimeout() {
226
+ cleanupAndReject(new Error("Download timed out"));
227
+ }
228
+
229
+ req.on("error", onReqError);
230
+ req.setTimeout(DOWNLOAD_TIMEOUT, onReqTimeout);
194
231
  });
195
232
  }
196
233
 
package/dist/index.js CHANGED
@@ -867,16 +867,26 @@ The user asks you to implement a new feature. You respond in multiple steps:
867
867
  deepseek: { model: "deepseek/deepseek-chat-v3", temperature: 0.1, maxTokens: 8192 },
868
868
  minimax: { model: "minimax/minimax-01", temperature: 0.1, maxTokens: 8192 }
869
869
  };
870
- const _initialProvider = PROVIDERS[currentProvider];
870
+ const os = __require("os");
871
+ let savedProvider = null;
871
872
  try {
872
- const configPath = path.join(__require("os").homedir(), ".apex-dev", "config.json");
873
+ const configPath = path.join(os.homedir(), ".apex-dev", "config.json");
873
874
  if (fs.existsSync(configPath)) {
874
875
  const savedConfig = JSON.parse(fs.readFileSync(configPath, "utf-8"));
875
- if (savedConfig[currentProvider] && !process.env[_initialProvider.envKey]) {
876
- process.env[_initialProvider.envKey] = savedConfig[currentProvider];
876
+ const hasEnvKey = Object.values(PROVIDERS).some((p) => process.env[p.envKey]);
877
+ if (!hasEnvKey) {
878
+ for (const [providerKey, provider] of Object.entries(PROVIDERS)) {
879
+ if (savedConfig[providerKey]) {
880
+ currentProvider = providerKey;
881
+ process.env[provider.envKey] = savedConfig[providerKey];
882
+ savedProvider = providerKey;
883
+ break;
884
+ }
885
+ }
877
886
  }
878
887
  }
879
888
  } catch (e) {}
889
+ const _initialProvider = PROVIDERS[currentProvider];
880
890
  const _initialKey = process.env[_initialProvider.envKey] || "no-key";
881
891
  let _internalClient = new OpenAI({
882
892
  apiKey: _initialKey,
@@ -4713,7 +4723,6 @@ function App() {
4713
4723
  ]
4714
4724
  });
4715
4725
  }
4716
- globalThis._App = App;
4717
4726
  async function main2() {
4718
4727
  if (process.env.APEX_LOCAL_SERVER === "1") {
4719
4728
  const srv = globalThis.require_server ? globalThis.require_server() : null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apex-dev",
3
- "version": "3.10.19",
3
+ "version": "3.10.20",
4
4
  "description": "Apex AI - a friendly agentic coding assistant for the terminal",
5
5
  "main": "dist/index.js",
6
6
  "bin": {