History

fix: honor provider environment homes

t3-code[bot] committed 2 months ago

Commit 42d46691 parent 29ab4d43 files · +35 −11Browse files

Unified · Split

3 files
  1. apps/server/src/usage/UsageService.test.ts +22 −3
  2. apps/server/src/usage/UsageService.ts +10 −2
  3. apps/web/src/components/usage/UsagePage.tsx +3 −6
apps/server/src/usage/UsageService.test.ts+22−3
@@ -1,5 +1,10 @@
1import * as NodeServices from "@effect/platform-node/NodeServices";1import * as NodeServices from "@effect/platform-node/NodeServices";
2import { ProviderDriverKind, ProviderInstanceId, type UsageDay } from "@t3tools/contracts";2import {
3 ProviderDriverKind,
4 ProviderInstanceEnvironmentVariableName,
5 ProviderInstanceId,
6 type UsageDay,
7} from "@t3tools/contracts";
3import { expect, it } from "@effect/vitest";8import { expect, it } from "@effect/vitest";
4import * as Effect from "effect/Effect";9import * as Effect from "effect/Effect";
5import * as Layer from "effect/Layer";10import * as Layer from "effect/Layer";
@@ -85,12 +90,26 @@ it.layer(NodeServices.layer)("UsageService", (it) => { · 79 unmodified lines
85 [ProviderInstanceId.make("codex-work")]: {90 [ProviderInstanceId.make("codex-work")]: {
86 driver: ProviderDriverKind.make("codex"),91 driver: ProviderDriverKind.make("codex"),
87 enabled: true,92 enabled: true,
88 config: { homePath: "/virtual/codex-work" },93 config: {},
94 environment: [
95 {
96 name: ProviderInstanceEnvironmentVariableName.make("CODEX_HOME"),
97 value: "/virtual/codex-work",
98 sensitive: false,
99 },
100 ],
89 },101 },
90 [ProviderInstanceId.make("codex-work-copy")]: {102 [ProviderInstanceId.make("codex-work-copy")]: {
91 driver: ProviderDriverKind.make("codex"),103 driver: ProviderDriverKind.make("codex"),
92 enabled: true,104 enabled: true,
93 config: { homePath: "/virtual/codex-work" },105 config: {},
106 environment: [
107 {
108 name: ProviderInstanceEnvironmentVariableName.make("CODEX_HOME"),
109 value: "/virtual/codex-work",
110 sensitive: false,
111 },
112 ],
94 },113 },
95 },114 },
96 }),115 }),
apps/server/src/usage/UsageService.ts+10−2
@@ -41,6 +41,7 @@ import { ServerConfig } from "../config.ts"; · 40 unmodified lines
41import * as ServerSettings from "../serverSettings.ts";41import * as ServerSettings from "../serverSettings.ts";
42import { resolveClaudeHomePath } from "../provider/Drivers/ClaudeHome.ts";42import { resolveClaudeHomePath } from "../provider/Drivers/ClaudeHome.ts";
43import { resolveCodexHomeLayout } from "../provider/Drivers/CodexHomeLayout.ts";43import { resolveCodexHomeLayout } from "../provider/Drivers/CodexHomeLayout.ts";
44import { mergeProviderInstanceEnvironment } from "../provider/ProviderInstanceEnvironment.ts";
44import { UsageAggregator } from "./usageAggregation.ts";45import { UsageAggregator } from "./usageAggregation.ts";
45import { parseRateTable, type RateTable } from "./usagePricing.ts";46import { parseRateTable, type RateTable } from "./usagePricing.ts";
46import {47import {
@@ -236,7 +237,10 @@ export const make = Effect.gen(function* () { · 189 unmodified lines
236 )) {237 )) {
237 const config = decodeClaudeSettings(instance.config ?? {});238 const config = decodeClaudeSettings(instance.config ?? {});
238 if (Option.isNone(config)) continue;239 if (Option.isNone(config)) continue;
239 const claudeHome = yield* resolveClaudeHomePath(config.value);240 const processEnv = mergeProviderInstanceEnvironment(instance.environment);
241 const claudeHome = yield* resolveClaudeHomePath({
242 homePath: config.value.homePath || processEnv.CLAUDE_CONFIG_DIR || "",
243 });
240 addDir("claude", yield* resolveClaudeTranscriptDir(claudeHome));244 addDir("claude", yield* resolveClaudeTranscriptDir(claudeHome));
241 }245 }
242 246
@@ -246,7 +250,11 @@ export const make = Effect.gen(function* () { · 3 unmodified lines
246 )) {250 )) {
247 const config = decodeCodexSettings(instance.config ?? {});251 const config = decodeCodexSettings(instance.config ?? {});
248 if (Option.isNone(config)) continue;252 if (Option.isNone(config)) continue;
249 const codexLayout = yield* resolveCodexHomeLayout(config.value);253 const processEnv = mergeProviderInstanceEnvironment(instance.environment);
254 const codexLayout = yield* resolveCodexHomeLayout({
255 ...config.value,
256 homePath: config.value.homePath || processEnv.CODEX_HOME || "",
257 });
250 addDir("codex", path.join(codexLayout.sharedHomePath, "sessions"));258 addDir("codex", path.join(codexLayout.sharedHomePath, "sessions"));
251 }259 }
252 return dirs;260 return dirs;
apps/web/src/components/usage/UsagePage.tsx+3−6
@@ -62,9 +62,6 @@ export function UsagePage() { · 61 unmodified lines
62 }62 }
63 return PROVIDER_ORDER.filter((provider) => enabled.has(provider));63 return PROVIDER_ORDER.filter((provider) => enabled.has(provider));
64 }, [environments, merged.staleEnvironments]);64 }, [environments, merged.staleEnvironments]);
65 const skeletonProviders = environments.some((environment) => environment.summary !== null)
66 ? providers
67 : PROVIDER_ORDER;
68 65
69 // Hold the content until every environment is terminal. Rendering merged66 // Hold the content until every environment is terminal. Rendering merged
70 // totals while devices are still answering makes every number on the page67 // totals while devices are still answering makes every number on the page
@@ -217,7 +214,7 @@ export function UsagePage() { · 146 unmodified lines
217 {settling ? (214 {settling ? (
218 <>215 <>
219 {environments.length > 1 ? <UsageDeviceStrip environments={environments} /> : null}216 {environments.length > 1 ? <UsageDeviceStrip environments={environments} /> : null}
220 <UsageSkeleton providers={skeletonProviders} />217 <UsageSkeleton />
221 </>218 </>
222 ) : (219 ) : (
223 <>220 <>
@@ -591,7 +588,7 @@ function UsageDeviceStrip({ · 367 unmodified lines
591 * Static stand-in with the loaded page's shape. No shimmer; blocks fill in588 * Static stand-in with the loaded page's shape. No shimmer; blocks fill in
592 * exactly once when the last device answers.589 * exactly once when the last device answers.
593 */590 */
594function UsageSkeleton({ providers }: { readonly providers: readonly UsageProviderKind[] }) {591function UsageSkeleton() {
595 return (592 return (
596 <>593 <>
597 <section className="grid gap-6 lg:grid-cols-[minmax(0,16rem)_minmax(0,1fr)]">594 <section className="grid gap-6 lg:grid-cols-[minmax(0,16rem)_minmax(0,1fr)]">
@@ -600,7 +597,7 @@ function UsageSkeleton({ providers }: { readonly providers: readonly UsageProvid · 2 unmodified lines
600 <div className="h-10 w-36 rounded-sm bg-muted" />597 <div className="h-10 w-36 rounded-sm bg-muted" />
601 <div className="h-4 w-32 rounded-sm bg-muted" />598 <div className="h-4 w-32 rounded-sm bg-muted" />
602 </div>599 </div>
603 {providers.map((provider) => (600 {PROVIDER_ORDER.map((provider) => (
604 <div key={provider} className="flex flex-col gap-1">601 <div key={provider} className="flex flex-col gap-1">
605 <div className="flex min-h-5 items-center justify-between gap-4">602 <div className="flex min-h-5 items-center justify-between gap-4">
606 <span className="flex items-center gap-2">603 <span className="flex items-center gap-2">

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t