@hienlh/ppm 0.9.77 → 0.9.79
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 +12 -0
- package/package.json +1 -1
- package/src/providers/claude-agent-sdk.ts +18 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.79] - 2026-04-10
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- **Silent hang on resume of never-completed sessions**: When a session's first attempt hung (no SDK `init` event received), subsequent messages tried to `resume` a non-existent JSONL file, causing the SDK subprocess to silently hang. Now detects missing SDK mapping and treats as a new session.
|
|
7
|
+
|
|
8
|
+
## [0.9.78] - 2026-04-10
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **SDK subprocess stderr logging**: Real-time stderr output from Claude CLI subprocess is now logged to server console for debugging hangs and crashes.
|
|
12
|
+
- **MCP servers diagnostic log**: Log which MCP servers are being passed to SDK query.
|
|
13
|
+
- **Query creation log**: Log when `query()` async iterator is created to confirm subprocess started.
|
|
14
|
+
|
|
3
15
|
## [0.9.77] - 2026-04-10
|
|
4
16
|
|
|
5
17
|
### Fixed
|
package/package.json
CHANGED
|
@@ -648,6 +648,14 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
648
648
|
// Resolve SDK's actual session ID for resume (may differ from PPM's UUID)
|
|
649
649
|
// For fork: use the source session's SDK id
|
|
650
650
|
const sdkId = shouldFork ? getSdkSessionId(forkSourceId!) : getSdkSessionId(sessionId);
|
|
651
|
+
// If messageCount > 0 (resumeSession ran) but no real SDK mapping exists,
|
|
652
|
+
// the session never received an init event (prior attempt hung/crashed).
|
|
653
|
+
// Treat as first message to avoid resuming a non-existent JSONL → silent hang.
|
|
654
|
+
const hasRealSdkMapping = getSessionMapping(sessionId) !== null && getSessionMapping(sessionId) !== sessionId;
|
|
655
|
+
const effectiveIsFirst = isFirstMessage || (!shouldFork && !hasRealSdkMapping);
|
|
656
|
+
if (effectiveIsFirst && !isFirstMessage) {
|
|
657
|
+
console.warn(`[sdk] session=${sessionId} no SDK mapping found — treating as new session (was isFirst=false)`);
|
|
658
|
+
}
|
|
651
659
|
// Fallback cwd: SDK needs a valid working directory even when no project is selected.
|
|
652
660
|
// On Windows daemons, undefined cwd can cause the subprocess to fail silently.
|
|
653
661
|
// Resolve path and validate existence — invalid cwd causes spawn to hang on Windows.
|
|
@@ -717,25 +725,29 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
717
725
|
console.warn(`[sdk] session=${sessionId} no account and no API key in env — Claude CLI will use its own auth (if any)`);
|
|
718
726
|
}
|
|
719
727
|
}
|
|
720
|
-
console.log(`[sdk] query: session=${sessionId} sdkId=${sdkId} isFirst=${isFirstMessage} fork=${shouldFork} cwd=${effectiveCwd} platform=${process.platform} accountMode=${!!account} permissionMode=${permissionMode} isBypass=${isBypass}`);
|
|
728
|
+
console.log(`[sdk] query: session=${sessionId} sdkId=${sdkId} isFirst=${isFirstMessage} effectiveIsFirst=${effectiveIsFirst} fork=${shouldFork} cwd=${effectiveCwd} platform=${process.platform} accountMode=${!!account} permissionMode=${permissionMode} isBypass=${isBypass}`);
|
|
721
729
|
|
|
722
730
|
// Read MCP servers from PPM DB (fresh per query — user may add/remove between chats)
|
|
723
731
|
const mcpServers = mcpConfigService.list();
|
|
724
732
|
const hasMcp = Object.keys(mcpServers).length > 0;
|
|
725
733
|
|
|
726
|
-
// Buffer subprocess stderr for crash diagnostics
|
|
734
|
+
// Buffer subprocess stderr for crash diagnostics + log in real-time
|
|
727
735
|
let stderrBuffer = "";
|
|
728
736
|
const stderrCallback = (chunk: string) => {
|
|
729
737
|
stderrBuffer += chunk;
|
|
730
|
-
// Keep only last 2KB to avoid unbounded growth
|
|
731
738
|
if (stderrBuffer.length > 2048) stderrBuffer = stderrBuffer.slice(-2048);
|
|
739
|
+
const trimmed = chunk.trim();
|
|
740
|
+
if (trimmed) console.log(`[sdk] session=${sessionId} stderr: ${trimmed.slice(0, 500)}`);
|
|
732
741
|
};
|
|
742
|
+
if (hasMcp) {
|
|
743
|
+
console.log(`[sdk] session=${sessionId} mcpServers: ${Object.keys(mcpServers).join(", ")}`);
|
|
744
|
+
}
|
|
733
745
|
|
|
734
746
|
const queryOptions: Record<string, any> = {
|
|
735
747
|
// On Windows, child_process.spawn("bun") fails with ENOENT — force node
|
|
736
748
|
...(process.platform === "win32" && { executable: "node" }),
|
|
737
|
-
sessionId:
|
|
738
|
-
resume: (
|
|
749
|
+
sessionId: effectiveIsFirst && !shouldFork ? sessionId : undefined,
|
|
750
|
+
resume: (effectiveIsFirst && !shouldFork) ? undefined : sdkId,
|
|
739
751
|
...(shouldFork && { forkSession: true }),
|
|
740
752
|
cwd: effectiveCwd,
|
|
741
753
|
systemPrompt: systemPromptOpt,
|
|
@@ -786,6 +798,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
786
798
|
this.streamingSessions.set(sessionId, { meta, query: initialQuery, controller: initialCtrl });
|
|
787
799
|
this.activeQueries.set(sessionId, initialQuery);
|
|
788
800
|
let eventSource: AsyncIterable<any> = initialQuery;
|
|
801
|
+
console.log(`[sdk] session=${sessionId} query() created, waiting for first SDK event...`);
|
|
789
802
|
|
|
790
803
|
// Helper: close the CURRENT streaming session (not stale closure refs).
|
|
791
804
|
// All retry paths must use this instead of closing captured variables directly.
|