@hienlh/ppm 0.4.1 → 0.4.2

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,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.2] - 2026-03-17
4
+
5
+ ### Added
6
+ - Subagent/tool hierarchy: Agent/Task tool cards show nested child tools (Bash, Read, etc.)
7
+ - Child events streamed with `parentToolUseId` and grouped under parent Agent card
8
+ - Collapsible subagent container with accent border and step counter
9
+ - Follow-up messages sent immediately (cancel + send) instead of queuing until done
10
+
11
+ ### Fixed
12
+ - Tool status indicators (spinner/checkmark) now correctly reflect completion state
13
+ - `pendingToolCount` no longer incremented for subagent child tools
14
+ - Top-level tool_results extracted directly from SDK `user` messages
15
+ - Windows: cloudflared binary download (`.exe` support)
16
+ - Windows: static file serving replaced hono serveStatic with Bun.file() for path compatibility
17
+
3
18
  ## [0.4.1] - 2026-03-17
4
19
 
5
20
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",
@@ -1,23 +1,59 @@
1
1
  import { Hono } from "hono";
2
- import { serveStatic } from "hono/bun";
3
2
  import { existsSync } from "node:fs";
4
- import { resolve } from "node:path";
3
+ import { resolve, join, extname } from "node:path";
5
4
 
6
5
  export const staticRoutes = new Hono();
7
6
 
8
7
  const DIST_DIR = resolve(import.meta.dir, "../../../dist/web");
9
8
 
10
- /** Serve static files from dist/web/ with SPA fallback */
11
- staticRoutes.use(
12
- "*",
13
- serveStatic({
14
- root: existsSync(DIST_DIR) ? DIST_DIR : undefined,
15
- rewriteRequestPath: (path) => path,
16
- }),
17
- );
9
+ /** MIME types for common static assets */
10
+ const MIME_TYPES: Record<string, string> = {
11
+ ".html": "text/html; charset=utf-8",
12
+ ".js": "application/javascript; charset=utf-8",
13
+ ".css": "text/css; charset=utf-8",
14
+ ".json": "application/json; charset=utf-8",
15
+ ".png": "image/png",
16
+ ".jpg": "image/jpeg",
17
+ ".jpeg": "image/jpeg",
18
+ ".gif": "image/gif",
19
+ ".svg": "image/svg+xml",
20
+ ".ico": "image/x-icon",
21
+ ".webp": "image/webp",
22
+ ".woff": "font/woff",
23
+ ".woff2": "font/woff2",
24
+ ".ttf": "font/ttf",
25
+ ".map": "application/json",
26
+ };
18
27
 
19
- /** SPA fallback — serve index.html for all unmatched routes */
28
+ /**
29
+ * Serve static files from dist/web/ using Bun.file() directly.
30
+ * Avoids hono/bun serveStatic which has path issues on Windows.
31
+ * Falls back to index.html for SPA routing.
32
+ */
20
33
  staticRoutes.get("*", async (c) => {
34
+ if (!existsSync(DIST_DIR)) {
35
+ return c.text("Frontend not built. Run: bun run build:web", 404);
36
+ }
37
+
38
+ // Try to serve the requested file
39
+ const urlPath = new URL(c.req.url).pathname;
40
+ const filePath = join(DIST_DIR, urlPath);
41
+
42
+ // Security: prevent directory traversal
43
+ if (!filePath.startsWith(DIST_DIR)) {
44
+ return c.text("Forbidden", 403);
45
+ }
46
+
47
+ if (existsSync(filePath) && !filePath.endsWith("/") && !filePath.endsWith("\\")) {
48
+ const file = Bun.file(filePath);
49
+ // Only serve if it's actually a file (not directory)
50
+ if (file.size > 0 || extname(filePath)) {
51
+ const mime = MIME_TYPES[extname(filePath).toLowerCase()] ?? "application/octet-stream";
52
+ return new Response(file, { headers: { "Content-Type": mime } });
53
+ }
54
+ }
55
+
56
+ // SPA fallback: serve index.html
21
57
  const indexPath = resolve(DIST_DIR, "index.html");
22
58
  if (existsSync(indexPath)) {
23
59
  return c.html(await Bun.file(indexPath).text());