@hienlh/ppm 0.12.8 → 0.12.9

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.12.9] - 2026-04-21
4
+
5
+ ### Fixed
6
+ - **Synthetic auth error leaking into history**: Filter SDK-persisted error messages (`isApiErrorMessage: true`, `error` field, or `model: "<synthetic>"` with auth/rate-limit text) when loading session history — raw "Failed to authenticate. API Error: 401 …" no longer shows up as an assistant bubble after reload
7
+
3
8
  ## [0.12.8] - 2026-04-21
4
9
 
5
10
  ### Changed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hienlh/ppm",
3
- "version": "0.12.8",
3
+ "version": "0.12.9",
4
4
  "description": "Personal Project Manager — mobile-first web IDE with AI assistance",
5
5
  "author": "hienlh",
6
6
  "license": "MIT",
package/src/index.ts CHANGED
File without changes
@@ -1576,6 +1576,29 @@ function parseSessionMessage(msg: { uuid: string; type: string; message: unknown
1576
1576
  const role = msg.type as "user" | "assistant";
1577
1577
  const parentId = (msg as any).parent_tool_use_id as string | undefined;
1578
1578
 
1579
+ // Filter synthetic SDK-generated error messages (auth failures, rate limits, etc.).
1580
+ // Structure: { isApiErrorMessage: true, error: "authentication_failed"|"rate_limit"|...,
1581
+ // message: { model: "<synthetic>", content: [{text: "Failed to authenticate..."}] } }
1582
+ // Our retry loop handles these; the raw text must not render in chat history.
1583
+ const isSdkErrorMessage =
1584
+ (msg as any).isApiErrorMessage === true ||
1585
+ typeof (msg as any).error === "string" ||
1586
+ (message && (message as any).model === "<synthetic>" &&
1587
+ Array.isArray(message.content) &&
1588
+ (message.content as Array<Record<string, unknown>>).some(
1589
+ (b) => b.type === "text" && typeof b.text === "string" &&
1590
+ /Failed to authenticate|API Error: 40[13]|hit your limit|rate.?limit/i.test(b.text as string),
1591
+ ));
1592
+ if (isSdkErrorMessage) {
1593
+ return {
1594
+ id: msg.uuid,
1595
+ role,
1596
+ content: "",
1597
+ timestamp: new Date().toISOString(),
1598
+ sdkUuid: msg.uuid,
1599
+ };
1600
+ }
1601
+
1579
1602
  // Parse content blocks for both user and assistant messages
1580
1603
  const events: ChatEvent[] = [];
1581
1604
  let textContent = "";