@hienlh/ppm 0.8.1 → 0.8.3

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,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.3] - 2026-03-23
4
+
5
+ ### Fixed
6
+ - **WSL timeout diagnostics**: Connection timeout error now detects WSL environment and suggests specific DNS/proxy troubleshooting steps
7
+ - **No-credentials warning**: Log warning when no account and no API key in env — helps diagnose why SDK subprocess hangs
8
+
9
+ ## [0.8.2] - 2026-03-23
10
+
11
+ ### Fixed
12
+ - **Heartbeat during SDK connection**: Keep "Connecting... (Xs)" indicator alive until real content arrives — previously stopped by `account_info` event, causing misleading "thinking" state during 3-minute SDK failures
13
+ - **Unknown API error hint**: "API error: unknown" now shows actionable guidance (check connectivity, re-add account, new session)
14
+
3
15
  ## [0.8.1] - 2026-03-23
4
16
 
5
17
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "MIT",
@@ -553,6 +553,14 @@ export class ClaudeAgentSdkProvider implements AIProvider {
553
553
  yield { type: "account_info" as const, accountId: account.id, accountLabel: account.label ?? account.email ?? "Unknown" };
554
554
  }
555
555
  const queryEnv = this.buildQueryEnv(meta.projectPath, account);
556
+
557
+ // Pre-flight: warn if no credentials at all (avoids 2-minute silent timeout)
558
+ if (!account) {
559
+ const hasApiKey = !!(queryEnv.ANTHROPIC_API_KEY || queryEnv.CLAUDE_CODE_OAUTH_TOKEN);
560
+ if (!hasApiKey) {
561
+ console.warn(`[sdk] session=${sessionId} no account and no API key in env — Claude CLI will use its own auth (if any)`);
562
+ }
563
+ }
556
564
  console.log(`[sdk] query: session=${sessionId} sdkId=${sdkId} isFirst=${isFirstMessage} fork=${shouldFork} cwd=${effectiveCwd} platform=${process.platform} accountMode=${!!account} permissionMode=${permissionMode} isBypass=${isBypass}`);
557
565
 
558
566
  // TODO: Remove when TS SDK fixes Windows stdin pipe buffering (see queryDirectCli() JSDoc for tracking issues)
@@ -797,6 +805,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
797
805
  rate_limit: "Rate limited by the API. Please wait and try again.",
798
806
  invalid_request: "Invalid request sent to the API.",
799
807
  server_error: "Anthropic API server error. Try again shortly.",
808
+ unknown: "API connection failed. Possible causes: network unreachable, expired OAuth token, or API outage. Try: 1) Check connectivity (`curl -s https://api.anthropic.com`), 2) Re-add account in Settings, 3) Create a new chat session.",
800
809
  };
801
810
  const hint = errorHints[assistantError] ?? `API error: ${assistantError}`;
802
811
  console.error(`[sdk] session=${sessionId} assistant error: ${assistantError}`);
@@ -130,9 +130,14 @@ async function runStreamLoop(sessionId: string, providerId: string, content: str
130
130
  clearInterval(heartbeat);
131
131
  console.error(`[chat] session=${sessionId} SDK connection timeout after ${elapsed}s`);
132
132
  logSessionEvent(sessionId, "ERROR", `SDK connection timeout after ${elapsed}s — subprocess may have failed to start`);
133
+ const projectPath = entry?.projectPath ?? "";
134
+ const isWSL = projectPath.startsWith("/home/") || projectPath.startsWith("/mnt/");
135
+ const wslHint = isWSL
136
+ ? "\n\nWSL detected — this is likely a network issue. Try from your WSL terminal:\n curl -s https://api.anthropic.com\nIf that fails, check WSL DNS settings (/etc/resolv.conf) or proxy configuration."
137
+ : "";
133
138
  safeSend(sessionId, {
134
139
  type: "error",
135
- message: `Claude SDK failed to respond after ${elapsed}s. Check that "claude" CLI works in your terminal, or try: ppm start -f`,
140
+ message: `Claude SDK failed to respond after ${elapsed}s. The API may be unreachable from this machine.${wslHint}\n\nGeneral troubleshooting:\n• Check internet connectivity\n• Run \`claude\` in your terminal to verify it works\n• Try: ppm start -f`,
136
141
  });
137
142
  abortController.abort();
138
143
  return;
@@ -146,8 +151,12 @@ async function runStreamLoop(sessionId: string, providerId: string, content: str
146
151
  const ev = event as any;
147
152
  const evType = ev.type ?? "unknown";
148
153
 
149
- // First event received — stop heartbeat, switch to streaming status
150
- if (!firstEventReceived) {
154
+ // First content event — stop heartbeat, switch to streaming status.
155
+ // Skip metadata events (account_info, streaming_status) that arrive before
156
+ // the SDK subprocess actually produces output — keeps heartbeat + "connecting"
157
+ // indicator alive until real content flows.
158
+ const isMetadataEvent = evType === "account_info" || evType === "streaming_status";
159
+ if (!firstEventReceived && !isMetadataEvent) {
151
160
  firstEventReceived = true;
152
161
  const waitMs = Date.now() - startTime;
153
162
  console.log(`[chat] session=${sessionId} first SDK event after ${waitMs}ms: type=${evType}`);