diff --git a/packages/core/src/oauth/page.ts b/packages/core/src/oauth/page.ts index 5d3e29f6..cd4e1e73 100644 --- a/packages/core/src/oauth/page.ts +++ b/packages/core/src/oauth/page.ts @@ -6,9 +6,8 @@ // offline and drop into any transport (`res.end(...)`, Effect `response.end`, // etc.). // -// The visual language mirrors the OpenCode app: the design tokens are a curated -// subset of the OC-2 semantic tokens in `packages/ui/src/styles/theme.css`, and -// the wordmark is the same geometry as `packages/ui/src/components/logo.tsx`. +// The design tokens are a curated subset of the OC-2 semantic tokens in +// `packages/ui/src/styles/theme.css`; the pages are branded as DevPass Code. // Keep this file in sync with those sources when the brand changes. export interface CallbackPageOptions { @@ -25,7 +24,9 @@ export function success(options?: CallbackPageOptions) { body: renderCard({ status: "success", headline: "Authorization successful", - message: provider ? `OpenCode is now connected to ${escapeHtml(provider)}.` : "OpenCode is now authorized.", + message: provider + ? `DevPass Code is now connected to ${escapeHtml(provider)}.` + : "DevPass Code is now authorized.", footnote: "You can close this window.", }), script: options?.autoClose === false ? undefined : AUTO_CLOSE_SCRIPT, @@ -40,10 +41,10 @@ export function error(detail: string, options?: CallbackPageOptions) { status: "error", headline: "Authorization failed", message: provider - ? `OpenCode couldn't finish connecting to ${escapeHtml(provider)}.` - : "OpenCode couldn't complete authorization.", + ? `DevPass Code couldn't finish connecting to ${escapeHtml(provider)}.` + : "DevPass Code couldn't complete authorization.", detail, - footnote: "Close this window and try again from OpenCode.", + footnote: "Close this window and try again from DevPass Code.", }), }) } @@ -100,7 +101,7 @@ function renderDocument(input: { title: string; body: string; script?: string }) - ${escapeHtml(input.title)} · OpenCode + ${escapeHtml(input.title)} · DevPass Code @@ -116,8 +117,8 @@ function bootstrapScript(options: BootstrapOptions) { var TOKEN_URL=new URL(${scriptString(options.tokenPath)},window.location.origin).href; (function(){ var card=document.getElementById("oc-card"),headline=document.getElementById("oc-headline"),message=document.getElementById("oc-message"),detail=document.getElementById("oc-detail"),footnote=document.getElementById("oc-footnote"); - function fail(text){card.dataset.status="error";headline.textContent="Authorization failed";message.textContent=PROVIDER?("OpenCode couldn't finish connecting to "+PROVIDER+"."):"OpenCode couldn't complete authorization.";if(text){detail.textContent=text;detail.hidden=false}footnote.textContent="Close this window and try again from OpenCode."} - function ok(){card.dataset.status="success";headline.textContent="Authorization successful";message.textContent=PROVIDER?("OpenCode is now connected to "+PROVIDER+"."):"OpenCode is now authorized.";detail.hidden=true;footnote.textContent="You can close this window.";setTimeout(function(){try{window.close()}catch(e){}},2500)} + function fail(text){card.dataset.status="error";headline.textContent="Authorization failed";message.textContent=PROVIDER?("DevPass Code couldn't finish connecting to "+PROVIDER+"."):"DevPass Code couldn't complete authorization.";if(text){detail.textContent=text;detail.hidden=false}footnote.textContent="Close this window and try again from DevPass Code."} + function ok(){card.dataset.status="success";headline.textContent="Authorization successful";message.textContent=PROVIDER?("DevPass Code is now connected to "+PROVIDER+"."):"DevPass Code is now authorized.";detail.hidden=true;footnote.textContent="You can close this window.";setTimeout(function(){try{window.close()}catch(e){}},2500)} try{ var hash=new URLSearchParams((window.location.hash||"").slice(1)); var search=new URLSearchParams(window.location.search||""); @@ -214,7 +215,8 @@ const STYLES = ` text-align: center; } .brand { display: flex; justify-content: center; margin-bottom: 1.75rem; } - .brand svg { height: 19px; width: auto; } + .brand .wordmark { font-size: 1.0625rem; font-weight: 500; letter-spacing: -0.01em; color: var(--oc-text-strong); } + .brand .wordmark b { font-weight: 700; } .status { display: flex; justify-content: center; margin-bottom: 1.125rem; } .icon { display: none; line-height: 0; } .icon svg { display: block; } @@ -249,25 +251,8 @@ const STYLES = ` @media (prefers-reduced-motion: reduce) { .spinner { animation: none; } } ` -// OpenCode wordmark — same path geometry as packages/ui/src/components/logo.tsx (Logo). -const WORDMARK = ` - - - - - - - - - - - - - - - - - ` +// DevPass Code wordmark — text-based, mirrors the TUI footer brand. +const WORDMARK = `DevPass Code` const ICON_CHECK = `` diff --git a/packages/devpass-code/bin/opencode b/packages/devpass-code/bin/devpass-code similarity index 100% rename from packages/devpass-code/bin/opencode rename to packages/devpass-code/bin/devpass-code diff --git a/packages/devpass-code/src/plugin/llmgateway/llmgateway.ts b/packages/devpass-code/src/plugin/llmgateway/llmgateway.ts index 02d4212c..ccc06733 100644 --- a/packages/devpass-code/src/plugin/llmgateway/llmgateway.ts +++ b/packages/devpass-code/src/plugin/llmgateway/llmgateway.ts @@ -35,7 +35,7 @@ interface LoopbackLogin { wait: () => Promise } -async function startLoopbackLogin(source: string): Promise { +async function startLoopbackLogin(source: string, org: "default" | "devpass"): Promise { let resolveKey!: (key: string) => void let rejectKey!: (error: Error) => void const keyPromise = new Promise((resolve, reject) => { @@ -90,6 +90,7 @@ async function startLoopbackLogin(source: string): Promise { callback, state, source, + org, name: "DevPass Code CLI", }) const url = `${appUrl()}/connect/cli?${params.toString()}` @@ -114,6 +115,12 @@ interface LlmGatewayPluginConfig { providerID: string label: string source: string + /** + * Which LLM Gateway org the minted key lives in: "devpass" bills the DevPass + * subscription (personal org), "default" bills pay-as-you-go credits on the + * user's default dashboard org. + */ + org: "default" | "devpass" } export function makeLlmGatewayPlugin(config: LlmGatewayPluginConfig) { @@ -126,7 +133,7 @@ export function makeLlmGatewayPlugin(config: LlmGatewayPluginConfig) { type: "oauth", label: "Log in with browser", authorize: async () => { - const { url, wait } = await startLoopbackLogin(config.source) + const { url, wait } = await startLoopbackLogin(config.source, config.org) open(url).catch(() => {}) return { url, @@ -163,10 +170,12 @@ export const LlmGatewayAuthPlugin = makeLlmGatewayPlugin({ providerID: "llmgateway", label: "LLM Gateway", source: "devpass-code", + org: "default", }) export const LlmGatewayDevPassAuthPlugin = makeLlmGatewayPlugin({ providerID: "llmgateway-devpass", label: "LLM Gateway DevPass", source: "devpass-code", + org: "devpass", })