Skip to content

Conversation

@anthonybailey
Copy link
Collaborator

@anthonybailey anthonybailey commented Jun 13, 2025

This PR implements a large change to build and l10n infrastructure. Starting with comprehensive documentation, followed by the implementation commits that fulfill it.

📖 Documentation

View the new documentation directly:

- Add complete L10N.md developer guide covering all modes, CLI usage, and workflows
- Update README.md with clear quick start and pnpm targets
- Update template.env with new L10N_ variable names and CI defaults
- Clarify l10n vs translation terminology throughout
@netlify
Copy link

netlify bot commented Jun 13, 2025

Deploy Preview for pauseai ready!

Name Link
🔨 Latest commit 0411514
🔍 Latest deploy log https://app.netlify.com/projects/pauseai/deploys/684ef5eefd043600081631ca
😎 Deploy Preview https://deploy-preview-366--pauseai.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 13, 2025

I'm going to be changing development and CI/CD to be able to run almost the same build. Local builds will continue to filter noise from logs but the CI/CD ones won't, for now. The first little commit allows that to work.

Anthony Bailey and others added 2 commits June 13, 2025 02:26
…ose mode

- Remove illegal `return` statement at ES module top level that caused SyntaxError
- Wrap main filtering logic in `else` block to prevent duplication when --verbose is used
- Fixes CI/CD build failures when --verbose flag is present in command line arguments

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
  Prevents accidental writes to production l10n cage from local development while
  supporting CI/CD workflows. Implements dynamic branch detection with fallbacks:
  - L10N_BRANCH environment override
  - CI environment detection (Netlify PR previews, branch deploys)
  - Current git branch as fallback

  Key safety features:
  - Blocks local development writes to main cage branch
  - Tests git authentication upfront to prevent failed commits
  - SSH auto-detection and switching for easier Git operations
  - CI environments error rather than fall back to dry-run with e.g. invalid API keys
  - Automatic branch creation and upstream tracking
  - Comprehensive test coverage (114 test lines)

  See L10N.md "Branch Safety System" section for usage.

A later commit will integrate the new feature.
@anthonybailey
Copy link
Collaborator Author

Cool. I should note, I have seen each of these same commits build here under CI/CD with all locales enabled too (on the l10-preview branch). I'm pushing them into the pull request individually to see them working for en-only too before we merge into main.

Anthony Bailey added 4 commits June 13, 2025 02:47
  Creates the Mode class implementing the three l10n operating modes:
  - en-only: No l10ns bothered, maximum speed (default for local dev)
  - dry-run: Uses captured l10ns only, no LLM calls (missing API key or --dry-run flag)
  - perform: Prompts LLMs to capture new l10ns into cage (valid API key + proper branch)

  Key features:
  - Centralized mode determination replacing scattered logic
  - Dropped dry-run based on isDev in favor of explicit API key env choice
  - Safe defaults prevent expensive operations in development
  - Clear mode announcements via mode.announce()
  - Branch safety integration for perform mode validation
  - Comprehensive test coverage (295 test lines, 100% coverage)

  See L10N.md "L10n Modes" section for behavior details.

A later commit will integrate this as yet unused new feature.
  Enables selective retranslation of specific files using familiar glob patterns.
  Supports standard minimatch syntax including wildcards, character classes, and brace expansion.

  Usage examples:
  - `pnpm l10n --force "*.md"` - All markdown files
  - `pnpm l10n --force "2024-*"` - Files with specific prefix
  - `pnpm l10n --force "{join,donate}.md"` - Multiple specific files
  - `pnpm l10n --force en.json proposal.md` - Mixed file types

  Key features:
  - Clean module extraction in force.ts with resolve() function
  - Comprehensive help system with examples and syntax guide
  - Integration tests against real filesystem (143 test lines)
  - Proper CLI argument parsing (fixed minimist boolean handling)

  See L10N.md "Force Mode Patterns" section for complete syntax guide.

This as yet unused new feature will be integrated in a later commit.
…hanges)

  Migrates from "translation" to "l10n" terminology with strategic commit splitting
  to preserve git file history. Renames core files and directory structure:

  Directory migration:
  - scripts/translation/ → scripts/l10n/

  Key file renames:
  - translate.ts → run.ts (main entry point)
  - translate-core.ts → heart.ts (core l10n logic)
  - Keep git-ops.ts, prompts.ts, utils.ts, etc.

  Limited terminology updates in moved files to ensure git detects renames.
  Note: This intermediate state does not build - completed in next commit.

  Part of comprehensive terminology migration to "l10n cage" architecture.
  See L10N.md for the new terminology and concepts.
…features

  As noted, this applies large changes to already moved git-ops, heart and run;
   also appropriately changes other files outside of scripts/l10n.
  Completes the transition from "translation" to "l10n cage" architecture with
   full integration of the new Mode, Branch Safety, and Force systems.

  Terminology migration:
  - Function names: translate() → l10nFromLLM(), translateOrLoad*() → retrieve*()
  - Parameter names: languageTag → locale, translationOptions → options
  - Type names: TranslationOptions → Options, TargetStrategy → Targeting
  - Comments and documentation: Complete "l10n cage" terminology throughout
  - Environment variables: Uses L10N_OPENROUTER_API_KEY, L10N_BRANCH

  Feature integration:
  - Mode system: Integrated in run.ts with mode.announce() and safe defaults
  - Branch safety: Integrated l10nCageBranch() and pushWithUpstream()
  - Force mode: Added resolveForcePatterns() and --force CLI support

  CLI simplification:
  - Removed redundant pnpm scripts (l10n:dry-run, l10n:estimate, etc.)
  - Unified to `pnpm l10n` with --dry-run, --force, --verbose flags
  - Updated dev/build integration for automatic l10n invocation

  Environment improvements:
  - isDev() now uses CI detection instead of NODE_ENV for consistent local defaults
  - Cache location: l10n-cage/ replaces src/temp/translations/
  - Package: Added minimatch dependency for glob pattern support

  See L10N.md for complete documentation of new architecture.
@anthonybailey
Copy link
Collaborator Author

The next two commits (together performing a terminology migration and using the features committed already) come as a pair only to try to maintain as much rename history as possible while changing a lot of content. If it gets lost, so be it.

Point is: things build before they appear. Things should build/work on CI/CD after the pair appears. That's what I'll check.

@anthonybailey anthonybailey marked this pull request as ready for review June 13, 2025 03:48
@anthonybailey anthonybailey requested a review from Wituareard June 13, 2025 03:48
@Wituareard
Copy link
Collaborator

Looks good to me at first glance, i'll take a closer look later

Remove some duplication and make more prominent upfront that for the most part you should let the CI/CD feed the l10ns.
People might feel obliged to read the whole thing carefully. Unless they are actually developing the l10n system itself, they do not! Let the CI/CD feed the l10ns.
@Wituareard
Copy link
Collaborator

The rest looks good

@Wituareard
Copy link
Collaborator

The GitHub Action needs a command that does as little as possible other than compiling a Paraglide runtime. It currently uses inlang:settings and I can't find something similar

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 14, 2025 via email

@Wituareard
Copy link
Collaborator

.github/workflows/pnpm-check.yml

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 14, 2025 via email

@Wituareard
Copy link
Collaborator

oops, accidentally rebased, sorry

@Wituareard Wituareard force-pushed the l10n-infrastructure-complete branch 2 times, most recently from 9a98f83 to 0f7f1ef Compare June 15, 2025 12:13
@Wituareard
Copy link
Collaborator

my git config is messed up, idk what's going on, won't try to merge again

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 15, 2025 via email

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 15, 2025 via email

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 15, 2025 via email

@Wituareard
Copy link
Collaborator

Wituareard commented Jun 15, 2025

Uhh I just wanted to merge the TS fixed from main here but accidentally rebased them on top of the PR commits. And how did you modify runtime.js? Does the script process the output of the paraglide compilation result?

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 15, 2025 via email

@Wituareard
Copy link
Collaborator

Okay yup found it, did you see the two review comments I left?

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 16, 2025 via email

@Wituareard
Copy link
Collaborator

Hmm I don't see a separate review either. Maybe it hasn't been published or something like that?

@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 16, 2025 via email

@Wituareard
Copy link
Collaborator

The links don't lead anywhere for me. You might have started a review and not posted it yet

@Wituareard
Copy link
Collaborator

@anthonybailey You can merge if you want

anthonybailey pushed a commit that referenced this pull request Jun 19, 2025
- Add complete L10N.md developer guide covering all modes, CLI usage, and workflows
- Update README.md with clear quick start and pnpm targets
- Update template.env with new L10N_ variable names and CI defaults
- Clarify l10n vs translation terminology throughout

These changes were originally reviewed in #366
anthonybailey pushed a commit that referenced this pull request Jun 19, 2025
…ose mode

- Remove illegal `return` statement at ES module top level that caused SyntaxError
- Wrap main filtering logic in `else` block to prevent duplication when --verbose is used
- Fixes CI/CD build failures when --verbose flag is present in command line arguments

These changes were originally reviewed in #366

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
anthonybailey pushed a commit that referenced this pull request Jun 19, 2025
Prevents accidental writes to production l10n cage from local development while
supporting CI/CD workflows. Implements dynamic branch detection with fallbacks:
- L10N_BRANCH environment override
- CI environment detection (Netlify PR previews, branch deploys)
- Current git branch as fallback

Key safety features:
- Blocks local development writes to main cage branch
- Tests git authentication upfront to prevent failed commits
- SSH auto-detection and switching for easier Git operations
- CI environments error rather than fall back to dry-run with e.g. invalid API keys
- Automatic branch creation and upstream tracking
- Comprehensive test coverage (114 test lines)

See L10N.md "Branch Safety System" section for usage.

A later commit will integrate the new feature.

These changes were originally reviewed in #366
anthonybailey pushed a commit that referenced this pull request Jun 19, 2025
Creates the Mode class implementing the three l10n operating modes:
- en-only: No l10ns bothered, maximum speed (default for local dev)
- dry-run: Uses captured l10ns only, no LLM calls (missing API key or --dry-run flag)
- perform: Prompts LLMs to capture new l10ns into cage (valid API key + proper branch)

Key features:
- Centralized mode determination replacing scattered logic
- Dropped dry-run based on isDev in favor of explicit API key env choice
- Safe defaults prevent expensive operations in development
- Clear mode announcements via mode.announce()
- Branch safety integration for perform mode validation
- Comprehensive test coverage (295 test lines, 100% coverage)

See L10N.md "L10n Modes" section for behavior details.

A later commit will integrate this as yet unused new feature.

These changes were originally reviewed in #366
anthonybailey pushed a commit that referenced this pull request Jun 19, 2025
Enables selective retranslation of specific files using familiar glob patterns.
Supports standard minimatch syntax including wildcards, character classes, and brace expansion.

Usage examples:
- `pnpm l10n --force "*.md"` - All markdown files
- `pnpm l10n --force "2024-*"` - Files with specific prefix
- `pnpm l10n --force "{join,donate}.md"` - Multiple specific files
- `pnpm l10n --force en.json proposal.md` - Mixed file types

Key features:
- Clean module extraction in force.ts with resolve() function
- Comprehensive help system with examples and syntax guide
- Integration tests against real filesystem (143 test lines)
- Proper CLI argument parsing (fixed minimist boolean handling)

See L10N.md "Force Mode Patterns" section for complete syntax guide.

This as yet unused new feature will be integrated in a later commit.

These changes were originally reviewed in #366
anthonybailey pushed a commit that referenced this pull request Jun 19, 2025
…hanges)

Migrates from "translation" to "l10n" terminology with strategic commit splitting
to preserve git file history. Renames core files and directory structure:

Directory migration:
- scripts/translation/ → scripts/l10n/

Key file renames:
- translate.ts → run.ts (main entry point)
- translate-core.ts → heart.ts (core l10n logic)
- Keep git-ops.ts, prompts.ts, utils.ts, etc.

Limited terminology updates in moved files to ensure git detects renames.
Note: This intermediate state does not build - completed in next commit.

Part of comprehensive terminology migration to "l10n cage" architecture.
See L10N.md for the new terminology and concepts.

These changes were originally reviewed in #366
anthonybailey pushed a commit that referenced this pull request Jun 19, 2025
…features

As noted, this applies large changes to already moved git-ops, heart and run;
 also appropriately changes other files outside of scripts/l10n.
Completes the transition from "translation" to "l10n cage" architecture with
 full integration of the new Mode, Branch Safety, and Force systems.

Terminology migration:
- Function names: translate() → l10nFromLLM(), translateOrLoad*() → retrieve*()
- Parameter names: languageTag → locale, translationOptions → options
- Type names: TranslationOptions → Options, TargetStrategy → Targeting
- Comments and documentation: Complete "l10n cage" terminology throughout
- Environment variables: Uses L10N_OPENROUTER_API_KEY, L10N_BRANCH

Feature integration:
- Mode system: Integrated in run.ts with mode.announce() and safe defaults
- Branch safety: Integrated l10nCageBranch() and pushWithUpstream()
- Force mode: Added resolveForcePatterns() and --force CLI support

CLI simplification:
- Removed redundant pnpm scripts (l10n:dry-run, l10n:estimate, etc.)
- Unified to `pnpm l10n` with --dry-run, --force, --verbose flags
- Updated dev/build integration for automatic l10n invocation

Environment improvements:
- isDev() now uses CI detection instead of NODE_ENV for consistent local defaults
- Cache location: l10n-cage/ replaces src/temp/translations/
- Package: Added minimatch dependency for glob pattern support

Also reintroduces "inlang:settings" target for "pnpm check" Action compatibility.

See L10N.md for complete documentation of new architecture.

These changes were originally reviewed in #366
@anthonybailey
Copy link
Collaborator Author

PR Successfully Merged via Reorganized Commits

This PR has been merged to main through a series of carefully reorganized commits to maintain clean project history.

What was done:

  • Cherry-picked and reorganized the commits from this PR
  • Combined related commits while keeping distinct features separate
  • Added PR reference to all commit messages
  • Pushed directly to main with the following structure:

Merged commits:

  1. 2f08476 - docs: comprehensive l10n documentation and environment updates
  2. 80498aa - fix: resolve filter-build-log.js syntax error and duplication in verbose mode
  3. cc82a48 - feat: implement l10n cage branch safety system
  4. b1f63ab - feat: implement l10n mode system with centralized determination
  5. 5e2590d - feat: implement l10n force mode with comprehensive glob pattern support
  6. a0df712 - refactor: l10n terminology migration part 1 (file renames + minimal changes)
  7. 19928c7 - feat/refactor: complete l10n terminology migration and integrate new features

All changes from this PR are now in main. The branch divergence was handled by rebasing on the latest main before merging.

Thank you @Wituareard for the reviews! 🎉

@anthonybailey
Copy link
Collaborator Author

Closing as completed - all changes have been merged to main via the reorganized commits listed above.

The deployment has completed successfully:

  • GitHub Actions build passed ✅
  • Changes are now live on the production website ✅

Thank you for the reviews and for this significant l10n infrastructure improvement!

@anthonybailey anthonybailey deleted the l10n-infrastructure-complete branch June 19, 2025 17:40
@anthonybailey
Copy link
Collaborator Author

anthonybailey commented Jun 19, 2025

(...

I forced pushed the state from main onto our (deliberately ephemeral) l10-preview branch since this builds with multiple locales, so should exercise the l10n machinery. There have been updates to some sources since we last ran this, so around ten pieces of content x two locales to localize.

First thing was that of course I'd renamed an environmental variable: it's L10N_OPENROUTER_API_KEY now.

For the moment I just supplied my own key for the variable in branch previews.

We have further different keys under OPENROUTER_API_KEY and TRANSLATION_OPENROUTER_API_KEY, probably from Nils and Joep respectively. We should discuss and housekeep.

After the easy fix, I am seeing contention for Git operations in subsequent failed builds.

8:29:17 PM: L10n process failed: GitError: fatal: Unable to create '/opt/build/repo/l10n-cage/.git/index.lock': File exists.
8:29:17 PM: Another git process seems to be running in this repository, e.g.
8:29:17 PM: an editor opened by 'git commit'. Please make sure all processes
8:29:17 PM: are terminated then try again. If it still fails, a git process
8:29:17 PM: may have crashed in this repository earlier:
8:29:17 PM: remove the file manually to continue.

Is entirely possible I've unserialized some previously serial read or commit or push operations in passing. The Git library we've been using is pretty crappy. Max processes seems the same as before.

Should be able to dig in locally.

...)

@anthonybailey
Copy link
Collaborator Author

Follow-up: Netlify CI Issues Resolved ✅

After merging this PR, we discovered Netlify was caching broken l10n-cage directories between builds, causing authentication failures and build errors. This has now been comprehensively fixed in commit e18e90b on l10-preview:

Key fixes:

  • CI cache cleanup: Force-remove cached l10n-cage in CI environments to ensure clean Git state
  • Fail-fast errors: Removed try-catch blocks so Git authentication failures immediately terminate builds (preventing wasted LLM costs)
  • Debug page fix: Removed problematic anchor syntax that confused LLM translations

Result: Netlify builds now complete successfully with proper error handling and no cache-related Git failures.

The l10n infrastructure is now fully robust and ready for production use. 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants