diff --git a/src/cli.ts b/src/cli.ts index c8edc38..0560d6a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -62,29 +62,29 @@ function wrapCommandAction Promise>(action: T program .name('localhero') - .description('CLI tool for automatic I18n translations with LocalHero.ai, more info at https://localhero.ai.') + .description('CLI tool for automatic I18n translations with Localhero.ai, more info at https://localhero.ai.') .version(getVersion()) .option('--debug', 'Show debug information when errors occur') .action(() => { - console.log('LocalHero.ai is an automatic I18n translation service that easily integrates with your dev workflow.'); + console.log('Localhero.ai is an automatic I18n translation service that easily integrates with your dev workflow.'); console.log(`\nVersion: ${getVersion()}`); console.log('\nπŸ‘ Set up your project with `npx @localheroai/cli init`'); console.log('πŸ’‘ Use --help to see available commands'); console.log('πŸ”— Visit https://localhero.ai for more information'); - console.log('\nWeΒ΄re LocalHero.ai, a small, bootstrapped company working to make'); + console.log("\nWe're Localhero.ai, a small, bootstrapped company working to make"); console.log('i18n simpler for developers like you. If you have any questions or'); console.log('feedback, just reach out to us at hi@localhero.ai. Thanks πŸ™Œ'); }); program .command('login') - .description('Authenticate with LocalHero.ai using an API key') + .description('Authenticate with Localhero.ai using an API key') .option('--api-key ', 'API key for non-interactive authentication') .action(wrapCommandAction((options: { apiKey?: string }) => login({ apiKey: options.apiKey }))); program .command('init') - .description('Initialize a new LocalHero.ai project') + .description('Initialize a new Localhero.ai project') .option('-y, --yes', 'Non-interactive mode: use flag values and never prompt') .option('--project-id ', 'Use an existing project (skips creation)') .option('--project-name ', 'Name for a new project (defaults to current directory name)') @@ -115,14 +115,14 @@ program program .command('pull') - .description('Pull updates from LocalHero.ai to your local files') + .description('Pull updates from Localhero.ai to your local files') .option('-v, --verbose', 'Show detailed progress information') .option('--changed-only', 'Only pull translations for keys changed in current branch') .action(wrapCommandAction((options: { verbose?: boolean; changedOnly?: boolean }) => pull(options))); program .command('push') - .description('Push updates from your local files to LocalHero.ai') + .description('Push updates from your local files to Localhero.ai') .option('-v, --verbose', 'Show detailed progress information') .option('-y, --yes', 'Skip confirmation prompt') .option('-f, --force', 'Push all files regardless of git changes') @@ -134,7 +134,7 @@ program program .command('clone') - .description('Clone all translations from LocalHero.ai to your local files') + .description('Clone all translations from Localhero.ai to your local files') .option('-v, --verbose', 'Show detailed progress information') .option('-f, --force', 'Force, override existing files') .action(wrapCommandAction((options: { verbose?: boolean; force?: boolean }) => clone(options))); diff --git a/src/commands/ci.ts b/src/commands/ci.ts index fc4af5f..a89bd4b 100644 --- a/src/commands/ci.ts +++ b/src/commands/ci.ts @@ -110,7 +110,7 @@ async function runSyncMode( const { console, configUtils, githubUtils, syncApi, updateTranslationFile } = deps; const verbose = options?.verbose || false; - console.log(chalk.blue('πŸ”„ Syncing translations from LocalHero...\n')); + console.log(chalk.blue('πŸ”„ Syncing translations from Localhero...\n')); const allFiles: SyncFile[] = []; let currentPage = 1; diff --git a/src/commands/login.ts b/src/commands/login.ts index 3315aca..17ef412 100644 --- a/src/commands/login.ts +++ b/src/commands/login.ts @@ -39,7 +39,7 @@ export async function login(deps: LoginDependencies = {}): Promise { const apiKey = providedApiKey || process.env.LOCALHERO_API_KEY || ( console.log('\nβ†’ Get your API key from: https://localhero.ai/api-keys'), - console.log('β†’ New to LocalHero? Sign up at: https://localhero.ai/signup'), + console.log('β†’ New to Localhero? Sign up at: https://localhero.ai/signup'), console.log('\nThe API key will be saved to .localhero_key, and automatically added to your .gitignore file.\n'), await promptService.getApiKey() ); diff --git a/src/commands/push.ts b/src/commands/push.ts index 3aeb668..f910f1d 100644 --- a/src/commands/push.ts +++ b/src/commands/push.ts @@ -103,7 +103,7 @@ export async function push( } else if (!yes) { const message = prune ? 'This will push your local translations and identify stale keys to prune.\nContinue?' - : 'This will push your local translations to LocalHero.ai.\nYour changes will be versioned in the API for easy tracking.\nContinue?'; + : 'This will push your local translations to Localhero.ai.\nYour changes will be versioned in the API for easy tracking.\nContinue?'; const confirmed = await prompt.confirm({ message, diff --git a/src/utils/github.ts b/src/utils/github.ts index 516d443..5baafa2 100644 --- a/src/utils/github.ts +++ b/src/utils/github.ts @@ -148,6 +148,9 @@ ${buildPythonToolSetup(pythonInstall)} - name: Extract messages sudo apt-get install -y -qq gettext ${pythonInstall} ${buildMakemessagesCommand(locales, pythonInstall)} + + # Optional: makemessages rewrites the creation-date header on every run, + # so without this line every CI run shows a one-line diff in every catalog. ${STRIP_POT_DATE} `; @@ -450,12 +453,15 @@ ${buildExtractStep(options)} - name: Translate if (appToken) { log.log('βœ“ Using GitHub App token'); + } else if (errorCode === 'invalid_api_key') { + log.warn('⚠️ Warning: API authentication failed. Using GITHUB_TOKEN instead (workflows will not trigger).'); + } else if (errorCode === 'github_app_not_installed') { + // A push authenticated with GITHUB_TOKEN never triggers downstream + // workflows, so required checks on this commit are left waiting with + // nothing to report. Staying silent here leaves that PR unexplained. + log.warn('⚠️ Warning: The Localhero GitHub App is not installed for this project. Using GITHUB_TOKEN instead, so checks on this commit will not run. Install the app to enable them.'); } else { - if (errorCode === 'invalid_api_key') { - log.warn('⚠️ Warning: API authentication failed. Using GITHUB_TOKEN instead (workflows will not trigger).'); - } else if (errorCode !== 'github_app_not_installed') { - log.warn('⚠️ Warning: Failed to fetch GitHub App token. Using GITHUB_TOKEN instead (workflows will not trigger).'); - } + log.warn('⚠️ Warning: Failed to fetch GitHub App token. Using GITHUB_TOKEN instead (workflows will not trigger).'); } return finalToken; diff --git a/tests/cli.test.js b/tests/cli.test.js index 3054e7b..b6710d7 100644 --- a/tests/cli.test.js +++ b/tests/cli.test.js @@ -14,7 +14,7 @@ describe('CLI basics', () => { it('displays info when no command is provided', () => { const output = execSync('node dist/cli.js').toString(); - expect(output).toContain('LocalHero.ai'); + expect(output).toContain('Localhero.ai'); expect(output).toContain('Visit https://localhero.ai for more information'); }); @@ -22,12 +22,12 @@ describe('CLI basics', () => { describe('command help texts', () => { it('login command help', () => { const output = execSync('node dist/cli.js login --help').toString(); - expect(output).toContain('Authenticate with LocalHero.ai'); + expect(output).toContain('Authenticate with Localhero.ai'); }); it('init command help', () => { const output = execSync('node dist/cli.js init --help').toString(); - expect(output).toContain('Initialize a new LocalHero.ai project'); + expect(output).toContain('Initialize a new Localhero.ai project'); }); it('translate command help', () => { @@ -37,7 +37,7 @@ describe('CLI basics', () => { it('sync command help', () => { const output = execSync('node dist/cli.js sync --help').toString(); - expect(output).toContain('Pull updates from LocalHero.ai'); + expect(output).toContain('Pull updates from Localhero.ai'); }); }); }); \ No newline at end of file diff --git a/tests/utils/github.test.ts b/tests/utils/github.test.ts index c9ae4a2..4b0bb13 100644 --- a/tests/utils/github.test.ts +++ b/tests/utils/github.test.ts @@ -607,7 +607,7 @@ describe('githubService', () => { ); }); - it('silently falls back to GITHUB_TOKEN when GitHub App not installed', async () => { + it('warns when falling back to GITHUB_TOKEN because the GitHub App is not installed', async () => { mockEnv.GITHUB_ACTIONS = 'true'; mockEnv.GITHUB_HEAD_REF = 'feature-branch'; mockEnv.GITHUB_TOKEN = 'github-token'; @@ -639,7 +639,9 @@ describe('githubService', () => { 'git remote set-url origin https://x-access-token:github-token@github.com/owner/repo.git', { stdio: 'pipe' } ); - expect(mockConsole.warn).not.toHaveBeenCalled(); + expect(mockConsole.warn).toHaveBeenCalledWith( + '⚠️ Warning: The Localhero GitHub App is not installed for this project. Using GITHUB_TOKEN instead, so checks on this commit will not run. Install the app to enable them.' + ); }); it('retries push on failure and succeeds on second attempt', async () => {