@hienlh/ppm 0.9.23 → 0.9.24

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 CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.9.24] - 2026-04-05
4
+
5
+ ### Fixed
6
+ - **Self-referencing proxy loop**: SDK subprocess inherited `ANTHROPIC_BASE_URL=/proxy` from shell env, calling PPM's own proxy instead of real Anthropic API → infinite 401 loop. Now detects and strips self-referencing proxy URL and paired API key from SDK env.
7
+
3
8
  ## [0.9.22] - 2026-04-05
4
9
 
5
10
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.9.23",
3
+ "version": "0.9.24",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "MIT",
@@ -170,9 +170,24 @@ export class ClaudeAgentSdkProvider implements AIProvider {
170
170
  resolvedOAuth = process.env.CLAUDE_CODE_OAUTH_TOKEN ?? "";
171
171
  }
172
172
 
173
+ // Detect self-referencing proxy: if shell env has ANTHROPIC_BASE_URL pointing to
174
+ // PPM's own /proxy endpoint (e.g. from `export` in the same shell), the SDK subprocess
175
+ // would call PPM's proxy instead of the real Anthropic API → infinite 401 loop.
176
+ const shellBaseUrl = process.env.ANTHROPIC_BASE_URL ?? "";
177
+ const isSelfProxy = shellBaseUrl.includes("/proxy");
178
+ if (isSelfProxy && shellBaseUrl) {
179
+ console.warn(`[sdk] Ignoring self-referencing ANTHROPIC_BASE_URL from shell: ${shellBaseUrl}`);
180
+ }
173
181
  const resolvedBaseUrl = providerConfig.base_url
174
- || process.env.ANTHROPIC_BASE_URL
182
+ || (isSelfProxy ? "" : shellBaseUrl)
175
183
  || "";
184
+ // Also clear API key from shell if it was paired with the self-referencing proxy URL
185
+ // (it's likely a PPM proxy token, not a real Anthropic key)
186
+ if (isSelfProxy && !settingsApiKey && !account && process.env.ANTHROPIC_API_KEY) {
187
+ resolvedApiKey = "";
188
+ resolvedOAuth = "";
189
+ console.warn(`[sdk] Clearing shell ANTHROPIC_API_KEY (paired with self-referencing proxy)`);
190
+ }
176
191
  const resolvedAuthToken = process.env.ANTHROPIC_AUTH_TOKEN ?? "";
177
192
 
178
193
  // Log resolved sources
@@ -180,13 +195,13 @@ export class ClaudeAgentSdkProvider implements AIProvider {
180
195
  console.log(`[sdk] Auth from settings api_key (length=${settingsApiKey.length})`);
181
196
  } else if (account) {
182
197
  console.log(`[sdk] Auth from PPM account (${account.accessToken.startsWith("sk-ant-oat") ? "OAuth" : "API key"})`);
183
- } else if (process.env.ANTHROPIC_API_KEY) {
198
+ } else if (process.env.ANTHROPIC_API_KEY && !isSelfProxy) {
184
199
  console.log(`[sdk] ANTHROPIC_API_KEY from shell env (length=${process.env.ANTHROPIC_API_KEY.length})`);
185
200
  }
186
201
  if (providerConfig.base_url) {
187
202
  console.log(`[sdk] ANTHROPIC_BASE_URL from settings: ${providerConfig.base_url}`);
188
- } else if (process.env.ANTHROPIC_BASE_URL) {
189
- console.log(`[sdk] ANTHROPIC_BASE_URL from shell env: ${process.env.ANTHROPIC_BASE_URL}`);
203
+ } else if (shellBaseUrl && !isSelfProxy) {
204
+ console.log(`[sdk] ANTHROPIC_BASE_URL from shell env: ${shellBaseUrl}`);
190
205
  }
191
206
 
192
207
  // Enable experimental agent teams if toggled on in provider settings