@hienlh/ppm 0.5.13 → 0.5.14

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.5.14] - 2026-03-18
4
+
5
+ ### Fixed
6
+ - **Windows: `claude` .cmd resolution** — `Bun.spawn` can't resolve `.cmd` wrapper scripts (npm globals) directly. Now spawns via `cmd /c claude` so Windows shell resolves PATH correctly
7
+
3
8
  ## [0.5.13] - 2026-03-18
4
9
 
5
10
  ### Fixed
@@ -42,6 +42,25 @@ settingSources: [],
42
42
 
43
43
  ---
44
44
 
45
+ ### Windows: SDK query() hangs — direct CLI fallback
46
+
47
+ **Problem**: On Windows, Bun subprocess stdin pipe buffering prevents SDK `query()` from working. Data written to stdin stays in buffer, never reaches the CLI child process → async iterator yields zero events → hangs forever.
48
+
49
+ **Root cause**: Python SDK had identical issue (#208), fixed with `asyncio.StreamWriter.drain()`. TypeScript SDK lacks this fix.
50
+
51
+ **Workaround**: Bypass SDK on Windows — spawn `claude -p --verbose --output-format stream-json` directly. CLI stream-json output uses same event types as SDK (`system/init`, `assistant`, `result`, `rate_limit_event`), so existing event handling works unchanged.
52
+
53
+ **Caveat**: CLI stream-json doesn't emit per-token `stream_event` deltas. Provider synthesizes them by chunking `assistant` message text into ~30-char pieces as synthetic `content_block_delta` events.
54
+
55
+ **Tracking**:
56
+ - Python SDK #208 (FIXED): stdin drain fix
57
+ - TS SDK #44 (OPEN): query() yields zero events
58
+ - TS SDK #64 (OPEN): bash tool hangs on empty output
59
+
60
+ **File**: `src/providers/claude-agent-sdk.ts` — `queryDirectCli()` method
61
+
62
+ ---
63
+
45
64
  ## WebSocket Chat Architecture
46
65
 
47
66
  ### Event flow: SDK → Provider → WS → Frontend
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.5.13",
3
+ "version": "0.5.14",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",
@@ -92,6 +92,17 @@ export class ClaudeAgentSdkProvider implements AIProvider {
92
92
  * Direct CLI fallback for Windows — spawns `claude -p` with stream-json output.
93
93
  * Workaround for Bun + Windows SDK subprocess pipe buffering issue.
94
94
  * Returns an async generator yielding the same event types as SDK query().
95
+ *
96
+ * TODO: Remove this fallback when TypeScript SDK fixes Windows stdin pipe buffering.
97
+ * Tracking issues:
98
+ * - Python SDK #208 (FIXED): https://github.com/anthropics/claude-agent-sdk-python/issues/208
99
+ * Fix: stdin drain() after writes — TypeScript SDK lacks equivalent fix.
100
+ * - TS SDK #44 (OPEN): https://github.com/anthropics/claude-agent-sdk-typescript/issues/44
101
+ * query() yields zero events for 3+ minutes on Windows.
102
+ * - TS SDK #64 (OPEN): https://github.com/anthropics/claude-agent-sdk-typescript/issues/64
103
+ * Bash tool hangs on empty output — related pipe/EOF handling issue.
104
+ * When these are resolved, switch back to SDK query() by removing the
105
+ * `useDirectCli` branch in sendMessage() and deleting this method.
95
106
  */
96
107
  private async *queryDirectCli(opts: {
97
108
  prompt: string;
@@ -119,10 +130,15 @@ export class ClaudeAgentSdkProvider implements AIProvider {
119
130
  // Permission mode
120
131
  args.push("--permission-mode", "bypassPermissions", "--dangerously-skip-permissions");
121
132
 
122
- console.log(`[sdk-cli] spawning: claude ${args.slice(0, 6).join(" ")}... cwd=${opts.cwd}`);
133
+ // On Windows, `claude` is a .cmd wrapper (npm global) — Bun.spawn can't resolve .cmd
134
+ // files directly. Use `cmd /c` to let the Windows shell find it via PATH.
135
+ const cmd = process.platform === "win32"
136
+ ? ["cmd", "/c", "claude", ...args]
137
+ : ["claude", ...args];
138
+ console.log(`[sdk-cli] spawning: ${cmd.slice(0, 7).join(" ")}... cwd=${opts.cwd}`);
123
139
 
124
140
  const proc = Bun.spawn({
125
- cmd: ["claude", ...args],
141
+ cmd,
126
142
  cwd: opts.cwd,
127
143
  stdout: "pipe",
128
144
  stderr: "pipe",
@@ -424,7 +440,8 @@ export class ClaudeAgentSdkProvider implements AIProvider {
424
440
  const queryEnv = { ...process.env, ...this.getProjectEnvOverrides(meta.projectPath) };
425
441
  console.log(`[sdk] query: session=${sessionId} sdkId=${sdkId} isFirst=${isFirstMessage} fork=${shouldFork} cwd=${effectiveCwd} platform=${process.platform}`);
426
442
 
427
- // On Windows, use direct CLI fallback (SDK query() hangs due to Bun subprocess pipe buffering)
443
+ // TODO: Remove when TS SDK fixes Windows stdin pipe buffering (see queryDirectCli() JSDoc for tracking issues)
444
+ // On Windows, SDK query() hangs because Bun subprocess stdin pipe never flushes to child process.
428
445
  const useDirectCli = process.platform === "win32";
429
446
  let eventSource: AsyncIterable<any>;
430
447