Detect plan tier from .claude.json; seed sane caps per tier (Pro/Max 5x/Max 20x)
This commit is contained in:
parent
106ad28f9f
commit
ef84257ddd
7 changed files with 236 additions and 7 deletions
|
|
@ -5,14 +5,21 @@
|
|||
disable as disableAutostart,
|
||||
isEnabled as isAutostartEnabled,
|
||||
} from "@tauri-apps/plugin-autostart";
|
||||
import { getSettings, setSettings, listDistros, getRoots } from "../ipc";
|
||||
import type { Settings, ResolvedRoots } from "../types";
|
||||
import {
|
||||
getSettings,
|
||||
setSettings,
|
||||
listDistros,
|
||||
getRoots,
|
||||
detectPlanTier,
|
||||
} from "../ipc";
|
||||
import type { Settings, ResolvedRoots, TierInfo } from "../types";
|
||||
|
||||
let { onClose }: { onClose: () => void } = $props();
|
||||
|
||||
let settings = $state<Settings | null>(null);
|
||||
let distros = $state<string[]>([]);
|
||||
let roots = $state<ResolvedRoots | null>(null);
|
||||
let tier = $state<TierInfo | null>(null);
|
||||
let busy = $state(false);
|
||||
let err = $state<string | null>(null);
|
||||
|
||||
|
|
@ -21,6 +28,7 @@
|
|||
settings = await getSettings();
|
||||
distros = await listDistros();
|
||||
roots = await getRoots();
|
||||
tier = await detectPlanTier();
|
||||
// Sync displayed autostart from the plugin's actual state.
|
||||
const enabled = await isAutostartEnabled();
|
||||
if (settings && settings.autostart !== enabled) {
|
||||
|
|
@ -31,6 +39,17 @@
|
|||
}
|
||||
});
|
||||
|
||||
function applyTierCaps() {
|
||||
if (!settings || !tier) return;
|
||||
settings = {
|
||||
...settings,
|
||||
caps: {
|
||||
block_tokens: tier.recommended_caps.block_tokens,
|
||||
weekly_tokens: tier.recommended_caps.weekly_tokens,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async function save() {
|
||||
if (!settings) return;
|
||||
busy = true;
|
||||
|
|
@ -59,12 +78,30 @@
|
|||
{#if err}<div class="error">{err}</div>{/if}
|
||||
|
||||
{#if settings}
|
||||
{#if tier}
|
||||
<div class="tier-card">
|
||||
<div class="row spread">
|
||||
<div>
|
||||
<div class="label" style="margin:0">Plan tier</div>
|
||||
<div>{tier.label}</div>
|
||||
</div>
|
||||
<button onclick={applyTierCaps} title="Set caps to recommended values for this tier">
|
||||
Use recommended
|
||||
</button>
|
||||
</div>
|
||||
<div class="muted hint">
|
||||
Approximate — Anthropic doesn't publish exact caps. Tune below
|
||||
once you actually hit a limit.
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="field">
|
||||
<div class="label">5-hour block cap (tokens)</div>
|
||||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
step="10000"
|
||||
step="100000"
|
||||
bind:value={settings.caps.block_tokens}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -74,7 +111,7 @@
|
|||
<input
|
||||
type="number"
|
||||
min="0"
|
||||
step="100000"
|
||||
step="1000000"
|
||||
bind:value={settings.caps.weekly_tokens}
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -147,6 +184,16 @@
|
|||
.actions { margin-top: auto; padding-top: 8px; border-top: 1px solid var(--border); }
|
||||
.roots { margin: 0; padding-left: 14px; max-height: 60px; overflow: auto; }
|
||||
.roots code { font-size: 10px; word-break: break-all; }
|
||||
.tier-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
padding: 8px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
}
|
||||
.hint { font-size: 10px; line-height: 1.3; }
|
||||
.error {
|
||||
background: rgba(255, 107, 107, 0.15);
|
||||
border: 1px solid var(--danger);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { listen, type UnlistenFn } from "@tauri-apps/api/event";
|
||||
import type { ResolvedRoots, Settings, UsageSnapshot } from "./types";
|
||||
import type { ResolvedRoots, Settings, TierInfo, UsageSnapshot } from "./types";
|
||||
|
||||
export const getSnapshot = (): Promise<UsageSnapshot> => invoke("get_snapshot");
|
||||
export const getSettings = (): Promise<Settings> => invoke("get_settings");
|
||||
|
|
@ -10,6 +10,7 @@ export const listDistros = (): Promise<string[]> => invoke("list_distros");
|
|||
export const getRoots = (): Promise<ResolvedRoots> => invoke("get_roots");
|
||||
export const forceRescan = (): Promise<void> => invoke("force_rescan");
|
||||
export const quitApp = (): Promise<void> => invoke("quit_app");
|
||||
export const detectPlanTier = (): Promise<TierInfo> => invoke("detect_plan_tier");
|
||||
|
||||
export const onUsageUpdated = (
|
||||
cb: (snap: UsageSnapshot) => void,
|
||||
|
|
|
|||
10
src/types.ts
10
src/types.ts
|
|
@ -58,3 +58,13 @@ export interface ResolvedRoots {
|
|||
wsl_distro: string | null;
|
||||
native_present: boolean;
|
||||
}
|
||||
|
||||
// Mirrors PlanTier in src-tauri/src/tier.rs. The Rust enum is serde-tagged
|
||||
// externally, so the wire shape is `"Max5x"` for unit variants and
|
||||
// `{ MaxOther: "raw-string" }` for tuple variants — we just keep it as
|
||||
// `unknown` here and rely on `label` for display.
|
||||
export interface TierInfo {
|
||||
tier: unknown;
|
||||
label: string;
|
||||
recommended_caps: Caps;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue