diff --git a/.changeset/install-clear-screen.md b/.changeset/install-clear-screen.md new file mode 100644 index 00000000..61525c0d --- /dev/null +++ b/.changeset/install-clear-screen.md @@ -0,0 +1,5 @@ +--- +'@pythoughts/pythinker-code': patch +--- + +Clear the terminal before the install script's animated intro so earlier shell output no longer interleaves with the logo animation. diff --git a/.changeset/oauth-pages-light-redesign.md b/.changeset/oauth-pages-light-redesign.md new file mode 100644 index 00000000..48d89936 --- /dev/null +++ b/.changeset/oauth-pages-light-redesign.md @@ -0,0 +1,5 @@ +--- +"@pythoughts/pythinker-code": patch +--- + +Restyle the browser OAuth sign-in confirmation pages for all providers to match the website's light design. diff --git a/apps/pythinker-code/src/constant/app.ts b/apps/pythinker-code/src/constant/app.ts index 7e0871b8..a5925214 100644 --- a/apps/pythinker-code/src/constant/app.ts +++ b/apps/pythinker-code/src/constant/app.ts @@ -67,8 +67,8 @@ export const ANTHROPIC_PLUGIN_MARKETPLACE_REPOSITORY = 'anthropics/claude-plugin export const CLAUDE_PLUGIN_MARKETPLACE_PATH = '.claude-plugin/marketplace.json'; export const ANTHROPIC_PLUGIN_MARKETPLACE_URL = `https://raw.githubusercontent.com/${ANTHROPIC_PLUGIN_MARKETPLACE_REPOSITORY}/HEAD/${CLAUDE_PLUGIN_MARKETPLACE_PATH}`; -export const PYTHINKER_CODE_INSTALL_SH_URL = 'https://pythinker.com/install.sh'; -export const PYTHINKER_CODE_INSTALL_PS1_URL = 'https://pythinker.com/install.ps1'; +export const PYTHINKER_CODE_INSTALL_SH_URL = 'https://code.pythinker.com/pythinker-code/install.sh'; +export const PYTHINKER_CODE_INSTALL_PS1_URL = 'https://code.pythinker.com/pythinker-code/install.ps1'; // Native install commands, split by platform. Use these for prompt copy and spawn calls only; do not assemble the strings elsewhere. export const NATIVE_INSTALL_COMMAND_UNIX = `curl -fsSL ${PYTHINKER_CODE_INSTALL_SH_URL} | bash`; diff --git a/apps/pythinker-code/test/cli/update/preflight.test.ts b/apps/pythinker-code/test/cli/update/preflight.test.ts index 646b12e7..183438b9 100644 --- a/apps/pythinker-code/test/cli/update/preflight.test.ts +++ b/apps/pythinker-code/test/cli/update/preflight.test.ts @@ -494,7 +494,7 @@ describe('runUpdatePreflight', () => { // pipefail must come before the pipeline so a failed `curl` is not masked // by the trailing `bash` exiting 0 (see "surfaces a failed curl" below). expect(script).toContain('set -o pipefail'); - expect(script).toContain('curl -fsSL https://pythinker.com/install.sh'); + expect(script).toContain('curl -fsSL https://code.pythinker.com/pythinker-code/install.sh'); expect(script).toContain('| bash'); } finally { Object.defineProperty(process, 'platform', { value: originalPlatform }); @@ -510,7 +510,7 @@ describe('runUpdatePreflight', () => { try { const { stdout, options } = captureOutput(); await expect(runUpdatePreflight('0.4.0', options)).resolves.toBe('continue'); - expect(stdout.join('')).toContain('irm https://pythinker.com/install.ps1 | iex'); + expect(stdout.join('')).toContain('irm https://code.pythinker.com/pythinker-code/install.ps1 | iex'); expect(promptForInstallChoice).not.toHaveBeenCalled(); expect(mocks.spawn).not.toHaveBeenCalled(); } finally { diff --git a/apps/pythinker-web/public/install.ps1 b/apps/pythinker-web/public/install.ps1 index c595be19..0bfe048d 100644 --- a/apps/pythinker-web/public/install.ps1 +++ b/apps/pythinker-web/public/install.ps1 @@ -6,10 +6,10 @@ # (added to the user PATH). # # Usage: -# irm https://pythinker.com/install.ps1 | iex +# irm https://code.pythinker.com/pythinker-code/install.ps1 | iex # # To pin a version when running the hosted script, set: -# $env:PYTHINKER_VERSION = "0.6.0"; irm https://pythinker.com/install.ps1 | iex +# $env:PYTHINKER_VERSION = "0.6.0"; irm https://code.pythinker.com/pythinker-code/install.ps1 | iex # # Or run the script directly: # .\install.ps1 -Version 0.6.0 @@ -26,8 +26,8 @@ $Repo = "Pythoughts-labs/pythinker-code" # CDN source of truth for the latest published version — same endpoint the # in-app updater reads, so a fresh install and an auto-update always agree. $CdnLatestUrl = "https://code.pythinker.com/pythinker-code/latest" -$InstallShUrl = "https://pythinker.com/install.sh" -$InstallPs1Url = "https://pythinker.com/install.ps1" +$InstallShUrl = "https://code.pythinker.com/pythinker-code/install.sh" +$InstallPs1Url = "https://code.pythinker.com/pythinker-code/install.ps1" $NoColor = $env:NO_COLOR try { [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 } catch {} @@ -148,6 +148,10 @@ function Stop-AntennaSpin { } function Write-LogoAnimated { + # The intro absolute-positions to screen rows (grid at 5-9, progress at + # 17), which assumes a clean screen. Clear it first — otherwise earlier + # shell output interleaves with the animation. + Write-Host -NoNewline "${ESC}[2J${ESC}[H" $rows = 5; $cols = 13 $frameMs = 60; $staggerMs = 40 if ($env:PYTHINKER_LOGO_FRAME_DELAY) { try { $frameMs = [int]([double]$env:PYTHINKER_LOGO_FRAME_DELAY * 1000) } catch {} } diff --git a/apps/pythinker-web/public/install.sh b/apps/pythinker-web/public/install.sh index 0032b487..c6605fb0 100755 --- a/apps/pythinker-web/public/install.sh +++ b/apps/pythinker-web/public/install.sh @@ -7,13 +7,13 @@ # ~/.local/bin/pythinker # # Usage: -# curl -fsSL https://pythinker.com/install.sh | bash +# curl -fsSL https://code.pythinker.com/pythinker-code/install.sh | bash # # # Pin a specific version: -# curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.6.0 +# curl -fsSL https://code.pythinker.com/pythinker-code/install.sh | bash -s -- --version 0.6.0 # # # Custom install prefix (default $HOME/.local): -# curl -fsSL https://pythinker.com/install.sh | bash -s -- --prefix /opt/pythinker +# curl -fsSL https://code.pythinker.com/pythinker-code/install.sh | bash -s -- --prefix /opt/pythinker # # Supported targets (matches release artifact names pythinker-code-.zip): # linux-x64 (Linux x86_64) @@ -21,7 +21,7 @@ # darwin-arm64 (macOS Apple Silicon) # darwin-x64 (macOS Intel) # -# Windows users: irm https://pythinker.com/install.ps1 | iex +# Windows users: irm https://code.pythinker.com/pythinker-code/install.ps1 | iex set -euo pipefail VERSION="" @@ -38,13 +38,13 @@ installs it at ~/.local/bin/pythinker Usage: - curl -fsSL https://pythinker.com/install.sh | bash + curl -fsSL https://code.pythinker.com/pythinker-code/install.sh | bash # Pin a specific version: - curl -fsSL https://pythinker.com/install.sh | bash -s -- --version 0.6.0 + curl -fsSL https://code.pythinker.com/pythinker-code/install.sh | bash -s -- --version 0.6.0 # Custom install prefix (default $HOME/.local): - curl -fsSL https://pythinker.com/install.sh | bash -s -- --prefix /opt/pythinker + curl -fsSL https://code.pythinker.com/pythinker-code/install.sh | bash -s -- --prefix /opt/pythinker Supported targets (matches release artifact names pythinker-code-.zip): linux-x64 (Linux x86_64) @@ -52,7 +52,7 @@ Supported targets (matches release artifact names pythinker-code-.zip): darwin-arm64 (macOS Apple Silicon) darwin-x64 (macOS Intel) -Windows users: irm https://pythinker.com/install.ps1 | iex +Windows users: irm https://code.pythinker.com/pythinker-code/install.ps1 | iex EOF } @@ -327,6 +327,11 @@ print_logo_animated() { local FRAME_DELAY="${PYTHINKER_LOGO_FRAME_DELAY:-0.06}" local STAGGER_DELAY="${PYTHINKER_LOGO_STAGGER_DELAY:-0.04}" + # The whole intro absolute-positions to screen rows (grid at 5-9, + # progress at 17), which assumes a clean screen. Clear it first — + # otherwise earlier shell output interleaves with the animation. + printf '\033[2J\033[H' + # Hide the text cursor while we redraw in place — otherwise the block # cursor on terminals like Terminal.app renders as a stray white block # at the cursor's current cell. Show it again before returning so the @@ -589,7 +594,7 @@ case "$os/$arch" in platform_display="macOS x64" ;; MINGW*/*|MSYS*/*|CYGWIN*/*) fail "On Windows, use the PowerShell installer: -powershell -c \"irm https://pythinker.com/install.ps1 | iex\"" ;; +powershell -c \"irm https://code.pythinker.com/pythinker-code/install.ps1 | iex\"" ;; *) fail "unsupported target: $os/$arch" ;; esac diff --git a/packages/oauth/src/oauth-pages.ts b/packages/oauth/src/oauth-pages.ts index 326c5122..84a051c5 100644 --- a/packages/oauth/src/oauth-pages.ts +++ b/packages/oauth/src/oauth-pages.ts @@ -39,46 +39,69 @@ const PYTHINKER_LOGO_SVG = ''; const SUCCESS_BADGE_SVG = - '' + @@ -99,7 +123,8 @@ function renderOAuthPage(options: { '

Pythinker Code

' + `
${options.badge}
` + `

${options.heading}

` + - `

${options.message}

` + + `

${options.message}

` + + `
${options.statusLine}
` + '' ); } @@ -110,6 +135,7 @@ export function renderOAuthSuccessPage(): string { heading: "You're logged in to Pythinker", message: 'You can close this tab and return to Pythinker.', badge: SUCCESS_BADGE_SVG, + statusLine: 'status: authenticated', }); } @@ -119,6 +145,7 @@ export function renderOpenAICodexOAuthSuccessPage(): string { heading: 'OpenAI Codex sign-in complete', message: 'You can close this tab and return to Pythinker Code.', badge: SUCCESS_BADGE_SVG, + statusLine: 'provider: openai-codex · status: authenticated', }); } @@ -128,5 +155,6 @@ export function renderOAuthErrorPage(): string { heading: 'Sign-in failed', message: 'The authorization server reported an error. Return to Pythinker for details.', badge: ERROR_BADGE_SVG, + statusLine: 'status: failed', }); }