Guidance for AI coding agents working in this repository. Skills are in Agent Skills format under .agents/skills/<name>/SKILL.md.
This is the Japanese translation project for Angular's official documentation site (angular.dev). The repository translates Angular documentation from English to Japanese and hosts the localized site at https://angular.jp.
For contributor-facing background, see CONTRIBUTING.md (setup, translation flow, guidelines), UPDATE_ORIGIN.md (manual origin update), and docs/TRANSLATION_WITH_AI.md (AI translation tool). This file adds the rules agents must follow.
origin/: Git submodule containing the upstreamangular/angularrepositoryadev-ja/: Japanese localized version containing both original English files (.en.md,.en.ts) and their Japanese translations (.md,.ts)tools/: Build and translation automation tools
- English source files:
filename.en.md,filename.en.ts,filename.en.json(snapshots of original content at translation time) - Japanese translated files:
filename.md,filename.ts,filename.json(localized versions) - Content location: Primarily in
adev-ja/src/content/for Markdown documentation - Tutorial structure: Interactive tutorials contain both content files (
README.md) and configuration files (config.json) defining page titles and editor settings
The project uses a custom TypeScript-based build system with Bazel integration:
- Build initialization copies and patches files from
origin/adev/tobuild/directory - Applies localization patches from
tools/adev-patches/ - Japanese content from
adev-ja/overlays the build structure
Workflow automation lives in .agents/skills/. Use the skills below before reaching for ad-hoc shell commands or new tooling.
| Skill | Purpose | When to use |
|---|---|---|
.agents/skills/update-origin/SKILL.md |
Single entry point for syncing upstream angular/angular into adev-ja. Covers branch, submodule update, diff classification, migration by role, verification, per-class commits, and PR. |
Any origin sync. Per-file migration always follows the role files in roles/ (delegated when possible). |
.agents/skills/translate-file/SKILL.md |
First-time translation of a new .en.md / .en.ts / .en.json file into Japanese with strict line-count and anchor-ID rules. |
A file is added upstream and you are ready to translate it. NOT for diff sync of an already-translated file (that is the update-origin flow). |
.agents/skills/prh-terminology/SKILL.md |
Manage the prh.yml terminology dictionary. |
Always before adopting a translation for a new technical term (see "Terminology management" below). |
These are instruction files for one batch of work each. If your harness supports delegating to sub-agents, pass the file as the instructions; otherwise follow it yourself in sequence. They are only used by the update-origin skill.
| Role | Purpose |
|---|---|
migrate-md-class-a.md |
Mirror low-risk markdown changes (code blocks, URLs, prose backtick identifiers). |
migrate-md-class-b.md |
Apply small line-localized markdown diffs preserving line correspondence. |
migrate-md-class-c.md |
Paragraph-level retranslation. |
defer-md-class-d.md |
Class-d defer in either d-additive or d-structural mode. |
migrate-md-roadmap.md |
Special handler for reference/roadmap.md (Completed-projects history accumulation). |
migrate-src-class-{a,b,c}.md |
Source-code (.ts / .html / .json) migration in three risk tiers. |
escalate-src-class-d.md |
Stops the workflow and reports class-d source files for resolution by a person. |
Run with pnpm exec tsx <script>.
| Script | Role |
|---|---|
classify-md-diff.ts |
Classifies each changed .en.md into class a/b/c/d. |
classify-src-diff.ts |
Same for source files. |
verify-migration.ts |
Hard gate: file presence, wc -l parity, structural-marker alignment (fences / headings / annotation prefixes). Use --base <ref> to scope the structural check (default main). |
verify-codeblock-sync.ts |
Hard gate: every diff-added line inside fenced code blocks must appear verbatim at the same line index in the JA .md. Catches class-a mirror omissions. |
# Initial setup and build (takes ~15 minutes first time)
pnpm install
pnpm build
# Start development server (http://localhost:4201)
# Always use pnpm start. Invoking Bazel targets directly (//adev:serve etc.) is prohibited.
pnpm start
# Force clean initialization and start
pnpm start --init
# Build for production
pnpm build
# Build without initialization
pnpm build --no-init# Update origin submodule to specific commit
pnpm update-origin <commit-hash>
# Update origin submodule without hash (re-copy current files)
pnpm update-origin
# List files that haven't been translated yet
pnpm run list-untranslated# Lint Japanese text using textlint
pnpm lint
# Fix automatically fixable lint issues
pnpm lint --fix
# Test patch application
pnpm test
# Enhanced patch testing for migrations
pnpm test && pnpm build --no-init # Full pipeline validationCommand clarification:
pnpm test: verifies all patches apply correctly to origin files (technical validation)pnpm lint: checks Japanese text quality using textlint rules (content validation)- When someone mentions "test failures", determine the context: patch application vs text quality issues
Enhanced patch testing workflow. When working with patch system changes:
- Pre-migration validation: run
pnpm testto ensure current patches apply cleanly - Post-change validation: run
pnpm testto verify new/modified patches work - Full pipeline verification: run
pnpm build --no-initto ensure patches integrate correctly with the build system - Incremental testing: test individual patches by temporarily moving others out of
tools/adev-patches/
CRITICAL: Verify that commands work on both macOS and Linux before using them in CI/CD workflows.
When writing shell commands that will run in CI (Linux environment):
- Test locally first: verify the command works on your development machine
- Check man pages: use
man [command]to verify flag compatibility across platforms - Prefer POSIX-compliant syntax: avoid platform-specific flags when possible
- Search for cross-platform alternatives: search "Linux [command] equivalent to macOS -flag" when encountering compatibility issues
- chmod symlink handling: macOS uses
-H, Linux requires thefind -Lpattern - find command: the
-Lflag works on both platforms for symlink traversal - sed command: macOS requires
-i '', Linux uses-i(use your editor's edit function instead to avoid this) - grep options: some GNU grep extensions are not available in macOS BSD grep
Before committing commands for CI workflows:
- Test the command locally
- Check
man [command]for flag descriptions - Search "[command] macOS Linux compatibility" if using non-standard flags
- Prefer portable alternatives (e.g.,
find -execoverxargswhen possible)
Example: making Bazel symlink outputs writable:
- Bad:
chmod -RH +w(macOS specific, fails on Linux) - Good:
find -L ${dir} -type f -exec chmod +w {} +(works on both platforms)
Single entry point: the update-origin skill (.agents/skills/update-origin/SKILL.md), started with the upstream commit hash.
All steps (branch creation, origin sync, diff classification, role-based migration, deterministic verification, per-directory commits, PR creation) are defined there. Per-file migration always follows the role files. When your harness can delegate to sub-agents, delegate each batch so that the orchestrating context stays isolated; otherwise follow the role files yourself one batch at a time.
Key invariants enforced by the skill:
wc -l <file.en.md> <file.md>must be identical for every markdown pair.- Structural-marker alignment: fenced code fences, headings, and line-prefix docs annotations sit at the same line index on both sides (verified by
verify-migration.ts). - Code-block content sync: every diff-added line inside a fenced code block must be mirrored verbatim to the JA-side
.mdat the same line index (verified byverify-codeblock-sync.ts). - Each
(class, directory)batch is one commit. Never combine. - Files are classified into a/b/c/d by
classify-md-diff.ts/classify-src-diff.ts. Class-d markdown splits into d-additive (preserve existing JA translation, insert new English sections at corresponding positions) and d-structural (full defer to upstream English;.md.bakretains prior translation). The orchestrator picks the mode by inspecting the actual diff content, not just +/- counts. Class-d source escalates to a person. roadmap.mdhas its own dedicated role (migrate-md-roadmap.md) because it accumulates "Completed projects" history that the generic class roles would discard.- Patch failures use the Safe Patch Update Procedure (see below). Never edit
.patchfiles manually.
- CRITICAL:
pnpm run translateis for NEW file translations only. Do NOT use it to apply diffs to existing translations. - Copy the English file to its
.en.*version when starting a new translation (applies to.md,.ts,.jsonfiles) - Maintain line-by-line correspondence between English and Japanese files for easier diff tracking
- Preserve technical terms in English where appropriate
- Add explicit heading IDs using
{#heading-id}syntax for cross-reference compatibility - File completeness requirement: every translated file must have a corresponding
.en.*backup file - Translation persistence: some file types may be auto-reverted by build processes or linters. Verify translations persist after build/lint operations.
CRITICAL: .en.* files are created ONLY when a Japanese translation exists.
- New English files from upstream (e.g.,
injectors.md): keep the original filename, do NOT rename to.en.md .en.*files purpose: backup snapshots of the English source at translation time, created when the Japanese translation is ready- When to create
.en.*files: only after translating the file. Copy the English source to the.en.*version simultaneously with creating the Japanese version. - Example workflow:
- Upstream adds
new-feature.md→ copy toadev-ja/src/content/new-feature.md(no.en.mdyet) - Ready to translate → create
new-feature.en.md(English backup) +new-feature.md(Japanese translation) together
- Upstream adds
- Never: rename untranslated English files to
.en.*. This breaks the localization workflow.
When certain files should NOT be localized (e.g., placeholder pages, deprecated content):
- Add an exclusion pattern to
tools/update-origin.tsin thelocalizedFilePatternsarray using negation syntax (!path/to/file) - Remove the existing file from
adev-ja/if it was previously copied - Example: to exclude
src/content/reference/concepts/overview.md:[ 'src/content/**/*.md', '!src/content/**/license.md', '!src/content/kitchen-sink.md', '!src/content/reference/concepts/overview.md', // ← Add here ]
- Commit the changes: remove the file from
adev-jaand updateupdate-origin.tsin the same commit
Important: use exact file paths for exclusions. Do NOT use glob patterns unless explicitly intending to exclude multiple files.
The project includes an AI translation tool using the Google Gemini API (details: docs/TRANSLATION_WITH_AI.md):
- Correct command:
pnpm run translate path/to/file.md - With auto-save:
pnpm run translate -w path/to/file.md - Processes Markdown files in heading-based blocks
- Applies two-stage processing: translation → proofreading
- Integrates with textlint for quality assurance
- Handles rate limiting and progress tracking
- The tool automatically creates
.en.mdbackup files and validates line count
翻訳ツール (pnpm run translate) 実行後、必ず以下を検証:
.en.mdファイルが英語原文であることを確認- 日本語が1文字でも含まれていたら翻訳ツールのバグ
head -5 filename.en.mdで先頭行を確認し、英語であることを検証- 異常検知時は即座に
cp origin/adev/src/content/path/to/file.md adev-ja/path/to/file.en.mdで修正
- ナビゲーションラベルと h1 見出しの一致確認
sub-navigation-data.tsの label と翻訳ファイルの h1 が一致するか確認- 不一致の場合、プロジェクト標準 (ナビゲーションラベル) に合わせて修正
- 確認コマンド:
grep -A2 "path: 'guide/path/to/file'" adev-ja/src/app/routing/sub-navigation-data.ts
- 行数の最終確認
wc -l file.md file.en.mdで行数が完全一致することを確認
明白な異常 (.en.md に日本語、行数不一致など) を発見したら、確認を待たずに上記の標準手順で修正する。
The project uses git patches to apply Japanese-specific modifications to the upstream Angular codebase:
- Patches are stored in
tools/adev-patches/*.patchand applied during the build process - When upstream changes occur, patches may fail and require manual updating
- Use
pnpm test(alias forpnpm run test:patch) to verify all patches apply correctly - Critical rule: never manually edit patch file newlines, as this frequently corrupts the patch format
- Patches handle UI text translations, styling adjustments, and Japanese-specific functionality
- UI translations:
translate-[component-name].patch(e.g.,translate-navigation.patch,translate-tutorial-label.patch) - Bug fixes:
fix-[issue-description].patch(e.g.,fix-canonical-host.patch) - Feature additions:
add-[feature-name].patch(e.g.,add-global-styles.patch) - Value replacements:
replace-[target].patch(e.g.,replace-environment-values.patch)
Use the patch system when:
- The file contains UI text that rarely changes structurally
- The file is a single component with isolated translations
- Upstream changes are typically additive rather than structural
- The file has minimal Japanese-specific logic beyond text translation
Keep separate files when:
- The file contains extensive Japanese-specific content or logic
- The file structure differs significantly from upstream
- The file is frequently modified with complex translation needs
- The file is part of content management (
.mdfiles inadev-ja/src/content/)
When upstream changes break existing patches:
- Navigate to the origin directory:
cd origin - Apply the required changes: edit the target files to match the desired patch outcome
- Generate the new patch:
git diff -- [target-files] > ../tools/adev-patches/[patch-name].patch - Restore the original files:
git checkout -- [target-files](inside theoriginsubmodule only) - Return to the root and test:
cd .. && pnpm test
This approach prevents patch file corruption and ensures clean patch generation.
CRITICAL: Angular.jp uses project-specific configurations that differ from upstream Angular.
The following configurations MUST use fixed values, NOT dynamic generation:
environment.tsindexName:'angular_jp_v19'- Upstream uses:
indexName: indexName(dynamic variable) - Angular.jp uses:
indexName: 'angular_jp_v19'(fixed string) - Reason: Angular.jp uses a dedicated Algolia index separate from upstream
- Upstream uses:
Patch update guidelines:
- ALWAYS review existing patch files before modifying them to understand Angular.jp-specific requirements
- DO NOT blindly apply upstream implementations: Angular.jp requirements take precedence
- VERIFY configurations after patch updates to ensure Angular.jp-specific values are preserved
- ASK the maintainers if uncertain about whether to use the upstream or the Angular.jp-specific implementation
Common mistakes to avoid:
- Assuming upstream's dynamic configuration should be used in Angular.jp
- Updating patches without checking existing Angular.jp-specific customizations
- Skipping verification of configuration values after patch updates
Migrating TO the patch system:
- Follow the safe patch update procedure to create the patch
- Update build configuration: remove migrated files from the
tools/update-origin.tslocalizedFilePatternsarray - Remove original files: delete both
.html/.tsand.en.html/.en.tsversions fromadev-ja/ - Test the full pipeline: run
pnpm testandpnpm build --no-initto verify patch system integration
Migrating FROM the patch system:
- Add to build configuration: include the files in the
tools/update-origin.tslocalizedFilePatternsarray - Create the file structure: copy the upstream file to
adev-ja/and create the.en.*backup version - Remove the patch: delete the corresponding patch file from
tools/adev-patches/ - Apply translations: use the appropriate translation tools to localize the separated files
tools/build.ts: main build orchestrationtools/lib/setup.ts: environment initialization and patchingtools/adev-patches/*.patch: localization patches applied to Angular source
tools/translator/: AI-powered translation systemtools/update-origin.ts: origin submodule sync management.textlintrc: Japanese text quality rulesprh.yml: terminology consistency rules
adev-ja/src/content/: main documentation contentadev-ja/src/app/sub-navigation-data.ts: navigation configurationadev-ja/shared-docs/components/: shared UI component translations
When working with long-running commands (build, lint, etc.):
- Immediate cleanup: stop unnecessary background processes as soon as the task is done to prevent resource waste
- Process monitoring: check a process's status before stopping it
- Selective execution: run only the commands required for the current task; avoid running parallel builds/lints unless specifically needed
- Example cleanup pattern: after successful build verification, stop any redundant build processes running in the background
On macOS, build processes may exhaust file descriptors. If builds fail, increase limits:
echo kern.maxfiles=65536 | sudo tee -a /etc/sysctl.conf
echo kern.maxfilesperproc=65536 | sudo tee -a /etc/sysctl.conf
sudo sysctl -w kern.maxfiles=65536
sudo sysctl -w kern.maxfilesperproc=65536
ulimit -n 65536- Maintain the original line count for easy diffing
- Follow Japanese technical writing standards (textlint enforced)
- Use katakana for foreign terms following Ministry of Education guidelines
- Add explicit heading IDs
{#id}when translating headings to preserve cross-references - Remove all symbols except hyphens from heading IDs (e.g.,
{#providing-context-with-llms.txt}becomes{#providing-context-with-llmstxt}) - For bullet points: add periods for complete sentences, omit for noun phrases
CRITICAL: Always read the English source (.en.*) file BEFORE translating or modifying Japanese text.
- Before any translation work: read the corresponding
.en.*file first to understand the original meaning and context - When evaluating translation quality: never judge "naturalness" or "correctness" from the Japanese text alone; always compare with the English source
- When fixing translations: always show the format
原文: [English] → 訳: [Japanese]to demonstrate source verification - Prohibited actions:
- Modifying Japanese text based on "what sounds natural" without checking the source
- Guessing the English source and translating based on assumptions
- Agreeing with a claim about the translation before actually reading the source text
- Required pattern: read the
.en.*file → understand the source meaning → apply an accurate translation → verify line count
When adding anchor IDs to Japanese headings (typically triggered by CI build errors):
- Reference the English version: check the corresponding
.en.mdfile for the proper anchor ID format - Comprehensive coverage: add anchor IDs to ALL
##and###level headings in the file, not selectively - Kebab-case format: use English-based kebab-case for anchor IDs (e.g.,
{#enable-reactive-forms-for-your-project}) - Skip top-level headings: do NOT add anchor IDs to
#(h1) page title headings - Commit immediately: use the
fix(docs): add anchor IDs to all headings in [filename]commit message format
- Italic formatting: use asterisk syntax
*text*instead of underscore_text_, because underscore syntax doesn't parse correctly when there are no spaces around Japanese text - HTML entity encoding: apply proper encoding for special characters (emojis, underscores) for better compatibility
- Line-prefix docs annotations: when a line begins with
IMPORTANT:,NOTE:,HELPFUL:,TIP:,CRITICAL:,WARNING:, orTLDR:(optionally after blockquote>markers), the prefix is a callout marker recognized by the adev build pipeline. Keep it literal in uppercase English (IMPORTANT: …); translate only the body after the colon. Never lowercase or translate the prefix (noTip:,重要:,警告:,ヒント:). The same words appearing inside a heading or mid-sentence are normal prose and may be translated naturally. Verified by the annotation-prefix drift check inverify-migration.ts.
- "essentials guide" → "基本ガイド" (not "必須ガイド")
- "source-of-truth" → "真の情報源" (not "真実の源")
- "eagerly" → "即座に" (when used in contrast to lazy loading)
- "Available Now:" → "最新情報:" (for UI labels, more friendly than the literal "利用可能:")
- HTML files: translate text content and labels; preserve Angular directives, classes, and routing paths
- TypeScript files: translate
labelfields in navigation; keeppath/contentPathexact; translateactiondescriptions in migrations - JSON files: translate user-facing strings; preserve technical identifiers and configuration values
When fixing textlint errors for redundant expressions:
- 冗長表現の修正: 「することもできます」→「たり...たりできます」など、文脈に応じて自然な表現に変更
- 意味の保持: 単純な文字列置換ではなく、元の文章の意味と可能性の表現を保つ
- 自然な日本語: 「〜も使用できます」「〜も利用します」など、より読みやすい表現を選択
- 文全体の調和: 個別の修正が文章全体の流れや論理構造を損なわないよう配慮
CRITICAL: Follow the prh-terminology skill (.agents/skills/prh-terminology/SKILL.md) for translation terminology consistency.
The project maintains a terminology dictionary in prh.yml.
- Before any translation work: check existing terminology rules
- For new technical terms: determine a consistent Japanese translation
- For katakana standardization: verify long vowel marks and spelling
- When adding terminology: create new rules for project-wide consistency
- For uncertain translations: look up the existing rules for Angular-specific terms first
Key categories:
- English preservation: Promise, Observable, Signal, Component
- Japanese standardization: 依存性の注入, 変更検知, 遅延読み込み
- Katakana consistency: サーバー, ユーザー, アプリケーション (with long vowel marks)
Rule: never guess terminology. Consult prh.yml through the skill to maintain project-wide consistency.
- Translation discussions occur in the Angular Japan User Group Discord
#翻訳channel - Create issues for coordination using the "Translation Checkout" label
- Pull requests require review and textlint compliance before merging
- The repository has strict rules preventing direct pushes to the main branch and merge commits
- Push your branch to your own fork and open the pull request from the fork to
angular/angular-ja:main - Run
git remote -vto confirm which remote points to your fork before pushing
CRITICAL: ALWAYS verify git state BEFORE executing git operations.
Before any git commit, push, or PR creation:
- Check staged changes: run
git diff --cachedto see exactly what will be committed - Verify the branch name: run
git branch --show-currentto confirm you're on the correct branch - Verify the remote before push: run
git remote -vto confirm the remote points to your fork - Review commit scope: ensure staged changes are logically related (e.g., don't mix patch updates with translation changes)
- Separate unrelated changes: if multiple unrelated changes are staged, reset and commit them separately
Common failure patterns to avoid:
- Committing without checking staged changes
- Creating commits that mix multiple unrelated concerns
- Pushing to the wrong remote or branch
- Creating PRs without verifying commit contents
Required commands before git operations:
# Before commit
git diff --cached # Verify staged changes
git status # Check overall state
# Before push
git log -1 # Verify last commit message and changes
git branch --show-current # Confirm branch name
# Before PR creation
git log <angular-ja-remote>/main..HEAD # Review all commits in PR- Commit messages: use conventional commit format (
feat(docs): translate ... to Japanese) - NO AI attribution: never include AI co-author credits, AI tool references, or generated-by statements in:
- Commit messages
- PR titles
- PR descriptions
- Keep commit messages and PR content clean and professional without AI tool acknowledgments
When creating pull requests for translations:
MANDATORY pre-PR checklist:
- Search for related issues FIRST: run
gh issue list --search "filename"or check Translation Checkout issues- Template fields exist for a reason: never write "N/A" without actually checking
- Each checkbox represents a project requirement, not an optional suggestion
- Verify all quality requirements: run
pnpm lintand check that line counts match
PR creation steps:
- Branch naming: use the
translate/<content-area>pattern (e.g.,translate/ai-design-patterns) - Template compliance: all PRs must follow the
.github/pull_request_template.mdstructure:- Include the translation checklist with checkboxes for guidelines and line count verification
- Fill "関連Issue" with
close #<issue-number>if a related issue exists - List translated files in the "備考" (remarks) section
- Keep additional details minimal: only essential file lists are needed
- Fork workflow: push to your own fork (not to
angular/angular-jadirectly) and open the PR againstangular/angular-ja:main
For origin syncs, the PR body and commit messages follow the "Public-surface hygiene" section of the update-origin skill.
The project requires:
- Node.js (version in
.node-version) - pnpm (version in the
packageManagerfield ofpackage.json) - Bazel (installed automatically during build)
- For AI translation: a Google API key with Gemini access
CRITICAL: some project tools have minimum version requirements that prevent functionality:
- gh CLI: requires v2.82.1+ due to the GitHub Projects (classic) deprecation (as of 2025-10)
- Symptoms:
gh pr editfails with a "GraphQL: Projects (classic) is being deprecated" error - Solution: upgrade the gh CLI with your package manager
- Symptoms:
- When CLI commands fail with cryptic errors, check tool versions FIRST before troubleshooting
When encountering technical errors (CLI failures, API errors, etc.):
- FIRST: search the web to check whether it is a known issue with a documented solution
- SECOND: check
--helpto verify you're using the command correctly - THIRD: try alternative approaches, only after confirming no known solution exists
- NEVER: keep retrying without research
Prohibited:
- Using
git checkoutorgit stashwhile investigating build errors (uncommitted changes would be lost) - Operations that leave the current branch