@hienlh/ppm 0.13.85 → 0.13.87
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 +16 -0
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/http-api.md +1 -1
- package/bun.lock +2248 -0
- package/bunfig.toml +2 -0
- package/dist/web/assets/{audio-preview-IRQhYBc9.js → audio-preview-CGlpWhgr.js} +1 -1
- package/dist/web/assets/{chat-tab-CrI_JDRj.js → chat-tab-ClgbHbv9.js} +3 -3
- package/dist/web/assets/{code-editor-N8XfT4X6.js → code-editor-DP88cKaY.js} +2 -2
- package/dist/web/assets/{conflict-editor-D8_hVdKW.js → conflict-editor-BeoPXciT.js} +1 -1
- package/dist/web/assets/{database-viewer-8FKzLz3e.js → database-viewer-Y8XylYBB.js} +1 -1
- package/dist/web/assets/{diff-viewer-BSYOjjem.js → diff-viewer-Cb3db8F6.js} +1 -1
- package/dist/web/assets/{docx-preview-CslyLNXJ.js → docx-preview-DjTD6P6D.js} +1 -1
- package/dist/web/assets/{extension-webview-C7Z_LmqG.js → extension-webview-Dk8ddm19.js} +1 -1
- package/dist/web/assets/{git-log-panel-BtIbMKyY.js → git-log-panel-LXe9nyBs.js} +1 -1
- package/dist/web/assets/{glide-data-grid-Di9XehtO.js → glide-data-grid-DZQDtmiO.js} +1 -1
- package/dist/web/assets/{image-preview-DgxEXvm1.js → image-preview-KEBnOWRV.js} +1 -1
- package/dist/web/assets/{index-Co68v-VL.js → index-DFsZOUXU.js} +4 -4
- package/dist/web/assets/keybindings-store-C1GQSO5O.js +1 -0
- package/dist/web/assets/{markdown-renderer-Cc8feZvH.js → markdown-renderer-C1aREZeW.js} +1 -1
- package/dist/web/assets/notification-store-CQPEClB9.js +1 -0
- package/dist/web/assets/{pdf-preview-2Kkq0YVS.js → pdf-preview-DpD6lwbe.js} +1 -1
- package/dist/web/assets/{port-forwarding-tab-Dm06Sss7.js → port-forwarding-tab-CeTcNsRi.js} +1 -1
- package/dist/web/assets/{postgres-viewer-Dk-JGd_M.js → postgres-viewer-aszM5Fcd.js} +1 -1
- package/dist/web/assets/{settings-tab-BMbf1_zH.js → settings-tab-Degb8F2N.js} +1 -1
- package/dist/web/assets/{sql-query-editor-BgiCruQe.js → sql-query-editor-Dd7g17iv.js} +1 -1
- package/dist/web/assets/{sqlite-viewer-DIQna_ds.js → sqlite-viewer-DoUIUYFP.js} +1 -1
- package/dist/web/assets/{system-monitor-tab-C3v0u_y6.js → system-monitor-tab-ByFvt-X1.js} +1 -1
- package/dist/web/assets/{terminal-tab-B7E6qSYt.js → terminal-tab-CbIyX35G.js} +1 -1
- package/dist/web/assets/{video-preview--2wXKPqj.js → video-preview-B7FgYduA.js} +1 -1
- package/dist/web/index.html +1 -1
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/schemas/ppm-config.schema.json +2 -2
- package/src/cli/commands/init.ts +2 -1
- package/src/index.ts +0 -0
- package/src/providers/claude-agent-sdk.ts +4 -3
- package/src/services/supervisor.ts +11 -4
- package/src/services/tunnel.service.ts +1 -1
- package/src/types/config.ts +1 -1
- package/src/web/components/settings/proxy-test-section.tsx +1 -0
- package/dist/web/assets/keybindings-store-COecqk_y.js +0 -1
- package/dist/web/assets/notification-store-B5j-Cm2O.js +0 -1
|
@@ -284,7 +284,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
284
284
|
// SDK uses `errors: string[]` array for error details
|
|
285
285
|
const errorsArr = Array.isArray(e.errors) ? (e.errors as string[]).join(" ") : "";
|
|
286
286
|
const msg = errorsArr || String(e.error ?? "");
|
|
287
|
-
if (msg.includes("429") || msg.toLowerCase().includes("rate limit") || msg.toLowerCase().includes("overloaded") ||
|
|
287
|
+
if (msg.includes("429") || msg.toLowerCase().includes("rate limit") || msg.toLowerCase().includes("overloaded") || /hit your (?:[\w-]+\s+)*limit/i.test(msg)) return 429;
|
|
288
288
|
if (msg.includes("401") || msg.toLowerCase().includes("unauthorized") || msg.toLowerCase().includes("invalid api key")) return 401;
|
|
289
289
|
}
|
|
290
290
|
return null;
|
|
@@ -518,6 +518,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
518
518
|
async listModels(): Promise<ModelOption[]> {
|
|
519
519
|
return [
|
|
520
520
|
{ value: "claude-sonnet-4-6", label: "Claude Sonnet 4.6" },
|
|
521
|
+
{ value: "claude-opus-4-8", label: "Claude Opus 4.8" },
|
|
521
522
|
{ value: "claude-opus-4-7", label: "Claude Opus 4.7" },
|
|
522
523
|
{ value: "claude-opus-4-6", label: "Claude Opus 4.6" },
|
|
523
524
|
{ value: "claude-haiku-4-5", label: "Claude Haiku 4.5" },
|
|
@@ -1167,7 +1168,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
1167
1168
|
if (textContent && /API Error:\s*401\b.*authentication_error/i.test(textContent)) {
|
|
1168
1169
|
assistantError = "authentication_failed";
|
|
1169
1170
|
console.warn(`[sdk] session=${sessionId} detected 401 in assistant text content — treating as auth error`);
|
|
1170
|
-
} else if (textContent && /hit your limit
|
|
1171
|
+
} else if (textContent && /hit your (?:[\w-]+\s+)*limit/i.test(textContent)) {
|
|
1171
1172
|
assistantError = "rate_limit";
|
|
1172
1173
|
console.warn(`[sdk] session=${sessionId} detected quota limit in assistant text content — treating as rate_limit`);
|
|
1173
1174
|
}
|
|
@@ -1448,7 +1449,7 @@ export class ClaudeAgentSdkProvider implements AIProvider {
|
|
|
1448
1449
|
hint = "\n\nHint: Network connectivity issue. Check your internet connection and firewall/proxy settings.";
|
|
1449
1450
|
} else if (detailLower.includes("401") || detailLower.includes("unauthorized") || detailLower.includes("invalid api key")) {
|
|
1450
1451
|
hint = "\n\nHint: Authentication failed. Try re-adding your account in Settings → Accounts.";
|
|
1451
|
-
} else if (
|
|
1452
|
+
} else if (/hit your (?:[\w-]+\s+)*limit/i.test(detailLower)) {
|
|
1452
1453
|
hint = "\n\nHint: Account quota exhausted. Will auto-switch on next message if other accounts are available.";
|
|
1453
1454
|
}
|
|
1454
1455
|
const fullMsg = sdkDetail ? `${baseMsg}\n${sdkDetail}${hint}` : baseMsg;
|
|
@@ -25,12 +25,13 @@ import { sdNotify } from "./sd-notify.ts";
|
|
|
25
25
|
const MAX_RESTARTS = 10;
|
|
26
26
|
const BACKOFF_BASE_MS = 1000;
|
|
27
27
|
const BACKOFF_MAX_MS = 60_000;
|
|
28
|
+
const TUNNEL_COOLDOWN_MS = 600_000; // 10min cooldown after MAX_RESTARTS before retrying tunnel
|
|
28
29
|
const STABLE_WINDOW_MS = 300_000; // 5min stable → reset restart counter
|
|
29
30
|
const SERVER_HEALTH_INTERVAL_MS = 30_000;
|
|
30
31
|
const SERVER_HEALTH_FAIL_THRESHOLD = 3;
|
|
31
32
|
const TUNNEL_PROBE_INTERVAL_MS = 30_000; // 30s — adopted tunnels have no `exited` promise
|
|
32
33
|
const TUNNEL_PROBE_FAIL_THRESHOLD = 3; // 3 HTTP failures before regenerating (PID check is instant)
|
|
33
|
-
const TUNNEL_URL_REGEX = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/;
|
|
34
|
+
const TUNNEL_URL_REGEX = /https:\/\/(?!api\.)[a-z0-9-]+\.trycloudflare\.com/;
|
|
34
35
|
const UPGRADE_CHECK_INTERVAL_MS = 900_000; // 15min
|
|
35
36
|
const UPGRADE_SKIP_INITIAL_MS = 300_000; // 5min delay before first check
|
|
36
37
|
const SELF_REPLACE_TIMEOUT_MS = 30_000; // 30s to wait for new supervisor
|
|
@@ -262,9 +263,12 @@ export async function spawnTunnel(port: number): Promise<void> {
|
|
|
262
263
|
tunnelRestarts++;
|
|
263
264
|
|
|
264
265
|
if (tunnelRestarts > MAX_RESTARTS) {
|
|
265
|
-
log("
|
|
266
|
+
log("WARN", `Tunnel exceeded ${MAX_RESTARTS} URL extraction failures, cooldown ${TUNNEL_COOLDOWN_MS}ms before retry`);
|
|
266
267
|
updateStatus({ shareUrl: null, tunnelPid: null });
|
|
267
|
-
|
|
268
|
+
await Bun.sleep(TUNNEL_COOLDOWN_MS);
|
|
269
|
+
tunnelRestarts = 0;
|
|
270
|
+
if (shuttingDown) return;
|
|
271
|
+
return spawnTunnel(port);
|
|
268
272
|
}
|
|
269
273
|
|
|
270
274
|
const delay = backoffDelay(tunnelRestarts);
|
|
@@ -293,8 +297,11 @@ export async function spawnTunnel(port: number): Promise<void> {
|
|
|
293
297
|
tunnelRestarts++;
|
|
294
298
|
|
|
295
299
|
if (tunnelRestarts > MAX_RESTARTS) {
|
|
296
|
-
log("
|
|
300
|
+
log("WARN", `Tunnel exceeded ${MAX_RESTARTS} restarts, cooldown ${TUNNEL_COOLDOWN_MS}ms before retry`);
|
|
297
301
|
updateStatus({ shareUrl: null, tunnelPid: null });
|
|
302
|
+
await Bun.sleep(TUNNEL_COOLDOWN_MS);
|
|
303
|
+
tunnelRestarts = 0;
|
|
304
|
+
if (!shuttingDown) return spawnTunnel(port);
|
|
298
305
|
return;
|
|
299
306
|
}
|
|
300
307
|
|
|
@@ -4,7 +4,7 @@ import { existsSync, unlinkSync, readFileSync, writeFileSync, renameSync } from
|
|
|
4
4
|
import { ensureCloudflared } from "./cloudflared.service.ts";
|
|
5
5
|
import { getPpmDir } from "./ppm-dir.ts";
|
|
6
6
|
|
|
7
|
-
const TUNNEL_URL_REGEX = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/;
|
|
7
|
+
const TUNNEL_URL_REGEX = /https:\/\/(?!api\.)[a-z0-9-]+\.trycloudflare\.com/;
|
|
8
8
|
const decoder = new TextDecoder();
|
|
9
9
|
|
|
10
10
|
/** Extract tunnel URL from cloudflared stderr output */
|
package/src/types/config.ts
CHANGED
|
@@ -104,7 +104,7 @@ export const DEFAULT_CONFIG: PpmConfig = {
|
|
|
104
104
|
|
|
105
105
|
const VALID_TYPES = ["agent-sdk", "cli", "mock"] as const;
|
|
106
106
|
const VALID_EFFORTS = ["low", "medium", "high"] as const;
|
|
107
|
-
const VALID_MODELS = ["claude-sonnet-4-6", "claude-opus-4-7", "claude-opus-4-6", "claude-haiku-4-5"] as const;
|
|
107
|
+
const VALID_MODELS = ["claude-sonnet-4-6", "claude-opus-4-8", "claude-opus-4-7", "claude-opus-4-6", "claude-haiku-4-5"] as const;
|
|
108
108
|
/** Allowed CLI commands for CLI providers (prevents command injection) */
|
|
109
109
|
const VALID_CLI_COMMANDS = ["cursor-agent", "codex", "gemini"] as const;
|
|
110
110
|
/** Only these values are allowed for default_provider in config */
|
|
@@ -160,6 +160,7 @@ function ProxyTestForm({ authKey, baseUrl }: ProxyTestDialogProps) {
|
|
|
160
160
|
className="h-8 w-full rounded-md border bg-background px-2 text-[11px]"
|
|
161
161
|
>
|
|
162
162
|
<option value="claude-sonnet-4-6">claude-sonnet-4-6</option>
|
|
163
|
+
<option value="claude-opus-4-8">claude-opus-4-8</option>
|
|
163
164
|
<option value="claude-opus-4-7">claude-opus-4-7</option>
|
|
164
165
|
<option value="claude-haiku-4-5-20251001">claude-haiku-4-5</option>
|
|
165
166
|
<option value="claude-opus-4-6">claude-opus-4-6</option>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./vendor-markdown-0Mxgxy0L.js";import"./api-client-bbJLzRVE.js";import{L as e}from"./index-Co68v-VL.js";export{e as useKeybindingsStore};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import"./vendor-markdown-0Mxgxy0L.js";import"./api-client-bbJLzRVE.js";import{W as e}from"./index-Co68v-VL.js";export{e as useNotificationStore};
|