summaryrefslogtreecommitdiffhomepage
path: root/src/app
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-10-14 17:29:03 +0900
committerAdam Malczewski <[email protected]>2026-10-14 17:29:03 +0900
commit8853a2df4c8b255d8c6638858f525ed5a0387f5f (patch)
tree68c71afe1ec59a58fd1fe2b30c486a31c33358f5 /src/app
parentd928bc86c35f590eb9113148bccf3c4ae56e8fa6 (diff)
downloaddispatch-web-8853a2df4c8b255d8c6638858f525ed5a0387f5f.tar.gz
dispatch-web-8853a2df4c8b255d8c6638858f525ed5a0387f5f.zip
feat(account-usage): Hyper daily credits card with allowance + reset-time editor
Diffstat (limited to 'src/app')
-rw-r--r--src/app/store.svelte.ts47
-rw-r--r--src/app/views/AccountUsagePane.svelte12
2 files changed, 54 insertions, 5 deletions
diff --git a/src/app/store.svelte.ts b/src/app/store.svelte.ts
index 7433f81..0a9cbd1 100644
--- a/src/app/store.svelte.ts
+++ b/src/app/store.svelte.ts
@@ -56,8 +56,13 @@ import {
subscribe as protocolSubscribe,
unsubscribe as protocolUnsubscribe,
} from "../core/protocol";
-import type { AccountUsageResult } from "../features/account-usage";
-import { normalizeAccountUsage } from "../features/account-usage";
+import type {
+ AccountUsageProviderId,
+ AccountUsageResult,
+ AccountUsageSettingsResult,
+ UpdateAccountUsageSettingsRequest,
+} from "../features/account-usage";
+import { normalizeAccountUsage, normalizeAccountUsageReport } from "../features/account-usage";
import type { ChatStore, HistorySync, MetricsSync } from "../features/chat";
import { createChatStore, migrateLegacyModelName } from "../features/chat";
import type { SetThinkingRequest, ThinkingResponse } from "../features/chat/reasoning-effort";
@@ -544,6 +549,15 @@ export interface AppStore {
*/
accountUsage(opts?: { readonly refresh?: boolean }): Promise<AccountUsageResult>;
/**
+ * Update a provider's usage settings (`PUT /usage/:provider/settings`; today
+ * only `hyper`: `dailyAllowance` + `resetAnchor` epoch-ms or null). Returns
+ * the provider's refreshed report.
+ */
+ setAccountUsageSettings(
+ provider: AccountUsageProviderId,
+ settings: UpdateAccountUsageSettingsRequest,
+ ): Promise<AccountUsageSettingsResult>;
+ /**
* Load the GLOBAL search-backend selection
* (`GET /search/config`): which engine backs the `web_search` tool's search
* mode. Not workspace-scoped — the selection is global. `unavailable: true`
@@ -2613,6 +2627,35 @@ export function createAppStore(opts?: CreateAppStoreOptions): AppStore {
}
},
+ async setAccountUsageSettings(
+ provider: AccountUsageProviderId,
+ settings: UpdateAccountUsageSettingsRequest,
+ ): Promise<AccountUsageSettingsResult> {
+ try {
+ const res = await fetchImpl(`${httpBase}/usage/${encodeURIComponent(provider)}/settings`, {
+ method: "PUT",
+ headers: { "content-type": "application/json" },
+ body: JSON.stringify(settings),
+ });
+ if (!res.ok) {
+ const errBody = (await res.json().catch(() => null)) as { error?: string } | null;
+ return {
+ ok: false,
+ error: errBody?.error ?? `Save usage settings failed (HTTP ${res.status})`,
+ };
+ }
+ const report = normalizeAccountUsageReport(await res.json());
+ return report
+ ? { ok: true, report }
+ : { ok: false, error: "Malformed usage settings response" };
+ } catch (err) {
+ return {
+ ok: false,
+ error: err instanceof Error ? err.message : "Save usage settings request failed",
+ };
+ }
+ },
+
async concurrencyStatus(): Promise<ConcurrencyStatusResult> {
try {
const res = await fetchImpl(`${httpBase}/concurrency/status`);
diff --git a/src/app/views/AccountUsagePane.svelte b/src/app/views/AccountUsagePane.svelte
index 4315d4c..09afb5f 100644
--- a/src/app/views/AccountUsagePane.svelte
+++ b/src/app/views/AccountUsagePane.svelte
@@ -1,16 +1,22 @@
<script lang="ts">
/**
- * The `account-usage` view — Claude + Codex subscription usage bars with
+ * The `account-usage` view — Claude + Codex + Hyper usage bars with
* on-track pace markers. GLOBAL (not workspace/conversation scoped), so it
* stays mounted across tab switches (no {#key}).
*/
- import { AccountUsageView, type LoadAccountUsage } from "../../features/account-usage";
+ import {
+ AccountUsageView,
+ type LoadAccountUsage,
+ type SaveAccountUsageSettings,
+ } from "../../features/account-usage";
import type { AppViewPorts } from "../view-ports";
let { ports }: { ports: AppViewPorts } = $props();
const store = $derived(ports.store);
const loadAccountUsage: LoadAccountUsage = (opts) => store.accountUsage(opts);
+ const saveAccountUsageSettings: SaveAccountUsageSettings = (provider, settings) =>
+ store.setAccountUsageSettings(provider, settings);
</script>
-<AccountUsageView load={loadAccountUsage} />
+<AccountUsageView load={loadAccountUsage} saveSettings={saveAccountUsageSettings} />