feat: add verified desktop ChatGPT subscription connection

This commit is contained in:
amosblomqvist
2026-10-24 12:17:08 +03:00
parent ae2fad56c4
commit 0fc6d4ab94
53 changed files with 2557 additions and 140 deletions
+15 -7
View File
@@ -294,9 +294,17 @@ function timeAgo(startedAt: number): string {
/** Run/stage cost at 3 decimals (pipeline pennies are real money at this
* scale); headline totals use 2. Null (unpriced model) renders "—". */
function fmtRunCost(dollars: number | null): string {
function fmtRunCost(dollars: number | null, subscription = false): string {
if (subscription) return dollars === null ? "ChatGPT plan" : `$${dollars.toFixed(3)} API + ChatGPT plan`;
return dollars === null ? "—" : `$${dollars.toFixed(3)}`;
}
function graphUsageLabel(costs: Pick<GraphCostSummary, "stages">): string {
const stages = [costs.stages.extraction, costs.stages.audit];
const plan = stages.some((stage) => (stage.subscriptionRuns ?? 0) > 0);
const priced = stages.some((stage) => stage.runs - stage.unpricedRuns - (stage.subscriptionRuns ?? 0) > 0);
const dollars = displayCostTotals(costs).totalDollars;
return plan ? (priced ? `$${dollars.toFixed(2)} API + ChatGPT plan` : "ChatGPT plan") : `$${dollars.toFixed(2)}`;
}
/**
* The cost figures the UI DISPLAYS (owner refinement round, 2026-09-24):
@@ -349,7 +357,7 @@ export function GraphCostControl({ costs }: { costs: GraphCostSummary }) {
open ? "text-foreground" : "text-muted-foreground hover:text-foreground"
}`}
>
${displayCostTotals(costs).totalDollars.toFixed(2)}
{graphUsageLabel(costs)}
</button>
</Hint>
{open && (
@@ -378,7 +386,7 @@ function GraphCostPanel({ costs }: { costs: GraphCostSummary }) {
];
// The displayed figures come from displayCostTotals (naming excluded —
// the pill and this panel must agree).
const { totalDollars, unpricedRuns } = displayCostTotals(costs);
const { unpricedRuns } = displayCostTotals(costs);
return (
<div className="w-80 max-w-[calc(100vw-1.5rem)] rounded-xl border bg-card/95 p-3 text-xs shadow-lg backdrop-blur">
<div className="mb-2 flex items-baseline justify-between">
@@ -386,7 +394,7 @@ function GraphCostPanel({ costs }: { costs: GraphCostSummary }) {
Graph pipeline costs
</span>
<span className="text-foreground tabular-nums">
${totalDollars.toFixed(2)}
{graphUsageLabel(costs)}
{unpricedRuns > 0 && (
<span className="text-muted-foreground"> · {unpricedRuns} unpriced</span>
)}
@@ -397,8 +405,8 @@ function GraphCostPanel({ costs }: { costs: GraphCostSummary }) {
<div key={label} className="flex items-baseline justify-between gap-2 text-[11px]">
<span className="shrink-0 text-muted-foreground">{label}</span>
<span className="min-w-0 text-right tabular-nums">
{fmtRunCost(stage.runs === 0 || (stage.unpricedRuns > 0 && stage.dollars === 0) ? null : stage.dollars)}
{stage.unpricedRuns > 0 && stage.dollars > 0 && (
{fmtRunCost(stage.runs - stage.unpricedRuns - (stage.subscriptionRuns ?? 0) <= 0 ? null : stage.dollars, (stage.subscriptionRuns ?? 0) > 0)}
{stage.unpricedRuns > 0 && (stage.runs - stage.unpricedRuns - (stage.subscriptionRuns ?? 0) > 0 || (stage.subscriptionRuns ?? 0) > 0) && (
<span className="text-muted-foreground"> +{stage.unpricedRuns} unpriced</span>
)}
<span className="text-muted-foreground">
@@ -422,7 +430,7 @@ function GraphCostPanel({ costs }: { costs: GraphCostSummary }) {
</span>
)}
</span>
<span className="shrink-0 tabular-nums">{fmtRunCost(run.dollars)}</span>
<span className="shrink-0 tabular-nums">{fmtRunCost(run.dollars, (run.subscriptionRuns ?? 0) > 0)}{run.dollars === null && run.subscriptionRuns === 1 ? " +1 unpriced" : ""}</span>
</div>
))}
</div>