├── dist ├── index.d.ts ├── index.d.ts.map ├── types.js.map ├── diff-detector.d.ts.map ├── types.js ├── inputs.d.ts.map ├── translator.d.ts.map ├── language-config.d.ts.map ├── parser.d.ts.map ├── heading-map.d.ts.map ├── reviewer.d.ts.map ├── inputs.d.ts ├── file-processor.d.ts.map ├── diff-detector.d.ts ├── language-config.js.map ├── translator.d.ts ├── language-config.d.ts ├── reviewer.d.ts ├── heading-map.d.ts ├── parser.d.ts ├── file-processor.d.ts ├── language-config.js ├── types.d.ts.map ├── diff-detector.js.map └── heading-map.js.map ├── docs ├── presentations │ ├── diagrams │ │ ├── workflow.png │ │ └── workflow.mmd │ ├── action-translation-sync.pdf │ ├── build.sh │ ├── README.md │ └── action-translation-sync.md ├── TEST-REPOSITORIES.md └── CLAUDE-MODELS.md ├── tool-alignment ├── test-fixtures │ ├── 08-extra-file │ │ ├── target │ │ │ ├── main.md │ │ │ └── local-guide.md │ │ ├── source │ │ │ └── main.md │ │ └── expected.json │ ├── 07-missing-file │ │ ├── target │ │ │ └── existing.md │ │ ├── source │ │ │ ├── existing.md │ │ │ └── new-chapter.md │ │ └── expected.json │ ├── 10-config-diverged │ │ ├── target │ │ │ └── _toc.yml │ │ ├── source │ │ │ └── _toc.yml │ │ └── expected.json │ ├── 13-multi-file-mixed │ │ ├── target │ │ │ ├── diverged.md │ │ │ ├── extra.md │ │ │ ├── _toc.yml │ │ │ └── aligned.md │ │ ├── source │ │ │ ├── _toc.yml │ │ │ ├── new.md │ │ │ ├── aligned.md │ │ │ └── diverged.md │ │ └── expected.json │ ├── 06-diverged-major │ │ ├── target │ │ │ └── guide.md │ │ ├── expected.json │ │ └── source │ │ │ └── guide.md │ ├── 09-config-identical │ │ ├── source │ │ │ └── _toc.yml │ │ ├── target │ │ │ └── _toc.yml │ │ └── expected.json │ ├── 01-aligned-perfect │ │ ├── target │ │ │ └── intro.md │ │ ├── source │ │ │ └── intro.md │ │ └── expected.json │ ├── 02-aligned-with-heading-map │ │ ├── target │ │ │ └── intro.md │ │ ├── source │ │ │ └── intro.md │ │ └── expected.json │ ├── 04-needs-review-missing-section │ │ ├── target │ │ │ └── economics.md │ │ ├── expected.json │ │ └── source │ │ │ └── economics.md │ ├── 05-needs-review-extra-section │ │ ├── target │ │ │ └── analysis.md │ │ ├── source │ │ │ └── analysis.md │ │ └── expected.json │ ├── 03-likely-aligned │ │ ├── target │ │ │ └── guide.md │ │ ├── source │ │ │ └── guide.md │ │ └── expected.json │ ├── 12-code-math-blocks │ │ ├── expected.json │ │ ├── target │ │ │ └── computing.md │ │ └── source │ │ │ └── computing.md │ ├── 11-subsections-nested │ │ ├── expected.json │ │ ├── target │ │ │ └── linear-algebra.md │ │ └── source │ │ │ └── linear-algebra.md │ ├── 14-code-integrity │ │ ├── target │ │ │ └── code-integrity.md │ │ ├── expected.json │ │ └── source │ │ │ └── code-integrity.md │ └── README.md ├── .gitignore ├── jest.config.js ├── tsconfig.json ├── package.json └── src │ └── triage.ts ├── tool-test-action-on-github ├── test-action-on-github-data │ ├── 18-delete-document-toc.yml │ ├── base-toc.yml │ ├── base-toc-zh-cn.yml │ ├── 20-rename-document-toc.yml │ ├── 17-new-document-toc.yml │ ├── base-minimal-zh-cn.md │ ├── 06-delete-section-minimal.md │ ├── base-minimal.md │ ├── 02-title-change-minimal.md │ ├── 16-pure-section-reorder-minimal.md │ ├── 04-section-reorder-minimal.md │ ├── 01-intro-change-minimal.md │ ├── 21-preamble-only-minimal.md │ ├── 03-section-content-minimal.md │ ├── 07-subsection-change-minimal.md │ ├── 05-add-section-minimal.md │ ├── 08-multi-element-minimal.md │ ├── 19-multi-file-minimal.md │ ├── 24-empty-sections-minimal.md │ ├── workflow-template.yml │ ├── 19-multi-file-lecture.md │ ├── 23-special-chars-lecture.md │ ├── 14-delete-subsection-lecture.md │ ├── base-lecture-zh-cn.md │ └── README.md ├── evaluate │ ├── tsconfig.json │ ├── package.json │ └── src │ │ └── types.ts └── reports │ └── README.md ├── .prettierrc.json ├── src ├── __tests__ │ ├── fixtures │ │ ├── e2e │ │ │ ├── 05-add-section-current-zh.md │ │ │ ├── 05-add-section-old-en.md │ │ │ ├── 06-delete-section-new-en.md │ │ │ ├── 02-title-change-current-zh.md │ │ │ ├── 03-section-content-current-zh.md │ │ │ ├── 06-delete-section-current-zh.md │ │ │ ├── 08-multi-element-current-zh.md │ │ │ ├── 02-title-change-old-en.md │ │ │ ├── 05-add-section-new-en.md │ │ │ ├── 06-delete-section-old-en.md │ │ │ ├── 08-multi-element-old-en.md │ │ │ ├── 03-section-content-old-en.md │ │ │ ├── 02-title-change-new-en.md │ │ │ ├── 04-section-reorder-current-zh.md │ │ │ ├── 07-subsection-change-current-zh.md │ │ │ ├── 03-section-content-new-en.md │ │ │ ├── 01-intro-change-current-zh.md │ │ │ ├── 04-section-reorder-new-en.md │ │ │ ├── 04-section-reorder-old-en.md │ │ │ ├── 07-subsection-change-old-en.md │ │ │ ├── 08-multi-element-new-en.md │ │ │ ├── 01-intro-change-old-en.md │ │ │ ├── 01-intro-change-new-en.md │ │ │ ├── 07-subsection-change-new-en.md │ │ │ └── README.md │ │ ├── intro-zh-cn.md │ │ ├── intro-old.md │ │ └── intro-new.md │ ├── parser-components.test.ts │ └── language-config.test.ts └── language-config.ts ├── tool-onboarding ├── src │ ├── analysis │ │ └── index.ts │ ├── discovery.ts │ └── __tests__ │ │ ├── discovery.test.ts │ │ └── constants.test.ts ├── .gitignore ├── jest.config.js ├── tsconfig.json ├── reports │ └── lecture-python-intro↔lecture-intro.zh-cn │ │ ├── summary.md │ │ └── debug │ │ └── cagan_adaptive-prose.md └── package.json ├── .eslintrc.json ├── tsconfig.json ├── .gitignore ├── jest.config.js ├── tool-bulk-translator ├── examples │ └── translate-lectures.sh ├── tsconfig.json └── package.json ├── package.json ├── examples ├── sample-lecture.md └── README.md └── action.yml /dist/index.d.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | //# sourceMappingURL=index.d.ts.map -------------------------------------------------------------------------------- /dist/index.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""} -------------------------------------------------------------------------------- /dist/types.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG"} -------------------------------------------------------------------------------- /docs/presentations/diagrams/workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/action-translation/main/docs/presentations/diagrams/workflow.png -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/08-extra-file/target/main.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 主要内容 3 | --- 4 | 5 | # 主要内容 6 | 7 | ## 概述 8 | 9 | 主要概述。 10 | -------------------------------------------------------------------------------- /docs/presentations/action-translation-sync.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/action-translation/main/docs/presentations/action-translation-sync.pdf -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/07-missing-file/target/existing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 现有章节 3 | --- 4 | 5 | # 现有章节 6 | 7 | ## 第一节 8 | 9 | 第一节的内容。 10 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/10-config-diverged/target/_toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: intro 3 | chapters: 4 | - file: chapter1 5 | - file: chapter2 6 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/target/diverged.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 分歧章节 3 | --- 4 | 5 | # 分歧章节 6 | 7 | ## 第一部分 8 | 9 | 第一部分的内容。 10 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/18-delete-document-toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: index 3 | chapters: 4 | - file: lecture-minimal 5 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/target/extra.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 额外指南 3 | --- 4 | 5 | # 额外指南 6 | 7 | ## 本地化内容 8 | 9 | 这是专门为中文用户准备的额外内容。 10 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/base-toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: index 3 | chapters: 4 | - file: lecture-minimal 5 | - file: lecture 6 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/source/_toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: intro 3 | chapters: 4 | - file: aligned 5 | - file: diverged 6 | - file: new 7 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/base-toc-zh-cn.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: index 3 | chapters: 4 | - file: lecture-minimal 5 | - file: lecture 6 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "es5", 4 | "singleQuote": true, 5 | "printWidth": 100, 6 | "tabWidth": 2, 7 | "arrowParens": "always" 8 | } 9 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/06-diverged-major/target/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 指南 3 | --- 4 | 5 | # 指南 6 | 7 | ## 简介 8 | 9 | 基本介绍。 10 | 11 | ## 总结 12 | 13 | 总结内容。 14 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/08-extra-file/source/main.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Main Content 3 | --- 4 | 5 | # Main Content 6 | 7 | ## Overview 8 | 9 | The main overview. 10 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/09-config-identical/source/_toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: intro 3 | chapters: 4 | - file: chapter1 5 | - file: chapter2 6 | - file: chapter3 7 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/09-config-identical/target/_toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: intro 3 | chapters: 4 | - file: chapter1 5 | - file: chapter2 6 | - file: chapter3 7 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/target/_toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: intro 3 | chapters: 4 | - file: aligned 5 | - file: diverged 6 | - file: extra 7 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/20-rename-document-toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: index 3 | chapters: 4 | - file: lecture-minimal 5 | - file: linear-algebra 6 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/01-aligned-perfect/target/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 简介 3 | --- 4 | 5 | # 简介 6 | 7 | ## 概述 8 | 9 | 本节提供主题概述。 10 | 11 | ## 入门 12 | 13 | 以下是如何开始学习基础知识。 14 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/07-missing-file/source/existing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Existing Chapter 3 | --- 4 | 5 | # Existing Chapter 6 | 7 | ## Section One 8 | 9 | Content for section one. 10 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/source/new.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: New Chapter 3 | --- 4 | 5 | # New Chapter 6 | 7 | ## Introduction 8 | 9 | This chapter needs to be translated. 10 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/17-new-document-toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: index 3 | chapters: 4 | - file: lecture-minimal 5 | - file: lecture 6 | - file: game-theory 7 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/08-extra-file/target/local-guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 本地指南 3 | --- 4 | 5 | # 本地指南 6 | 7 | ## 中国用户须知 8 | 9 | 这是专门为中国用户准备的本地化内容。 10 | 11 | ## 相关资源 12 | 13 | 中文学习资源链接。 14 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/10-config-diverged/source/_toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: intro 3 | chapters: 4 | - file: chapter1 5 | - file: chapter2 6 | - file: chapter3 7 | - file: chapter4 8 | - file: chapter5 9 | -------------------------------------------------------------------------------- /tool-alignment/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | 4 | # Build output 5 | dist/ 6 | 7 | # Reports (generated, can keep examples) 8 | # reports/ 9 | 10 | # OS files 11 | .DS_Store 12 | 13 | # IDE 14 | .vscode/ 15 | .idea/ 16 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/source/aligned.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Aligned Chapter 3 | --- 4 | 5 | # Aligned Chapter 6 | 7 | ## Section A 8 | 9 | Content for section A. 10 | 11 | ## Section B 12 | 13 | Content for section B. 14 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/target/aligned.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 对齐章节 3 | heading-map: 4 | section-a: "A节" 5 | section-b: "B节" 6 | --- 7 | 8 | # 对齐章节 9 | 10 | ## A节 11 | 12 | A节的内容。 13 | 14 | ## B节 15 | 16 | B节的内容。 17 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/02-aligned-with-heading-map/target/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 简介 3 | heading-map: 4 | overview: "概述" 5 | getting-started: "入门" 6 | --- 7 | 8 | # 简介 9 | 10 | ## 概述 11 | 12 | 本节提供主题概述。 13 | 14 | ## 入门 15 | 16 | 以下是如何开始学习基础知识。 17 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/04-needs-review-missing-section/target/economics.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 经济学基础 3 | --- 4 | 5 | # 经济学基础 6 | 7 | ## 供给与需求 8 | 9 | 供给与需求的基本概念。 10 | 11 | ## 市场均衡 12 | 13 | 市场如何达到均衡。 14 | 15 | ## 消费者行为 16 | 17 | 消费者如何做出决策。 18 | 19 | ## 总结 20 | 21 | 章节总结和要点。 22 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/05-needs-review-extra-section/target/analysis.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 数据分析 3 | --- 4 | 5 | # 数据分析 6 | 7 | ## 加载数据 8 | 9 | 如何从各种来源加载数据。 10 | 11 | ## 清理数据 12 | 13 | 数据清理技术。 14 | 15 | ## 可视化 16 | 17 | 创建图表。 18 | 19 | ## 中文资源 20 | 21 | 本节包含中文特有的学习资源和参考资料。 22 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/05-add-section-current-zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | heading-map: 7 | Supply and Demand: 供给与需求 8 | --- 9 | 10 | # 经济学讲座 11 | 12 | 这是介绍段落。 13 | 14 | ## 供给与需求 15 | 16 | 供给和需求是经济学的基本概念。 17 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/01-aligned-perfect/source/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | --- 4 | 5 | # Introduction 6 | 7 | ## Overview 8 | 9 | This section provides an overview of the topic. 10 | 11 | ## Getting Started 12 | 13 | Here is how to get started with the basics. 14 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/07-missing-file/source/new-chapter.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: New Chapter 3 | --- 4 | 5 | # New Chapter 6 | 7 | ## Introduction 8 | 9 | This is a new chapter that hasn't been translated yet. 10 | 11 | ## Main Content 12 | 13 | The main content of the new chapter. 14 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/02-aligned-with-heading-map/source/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | --- 4 | 5 | # Introduction 6 | 7 | ## Overview 8 | 9 | This section provides an overview of the topic. 10 | 11 | ## Getting Started 12 | 13 | Here is how to get started with the basics. 14 | -------------------------------------------------------------------------------- /tool-onboarding/src/analysis/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Analysis module exports 3 | */ 4 | 5 | export { compareCodeBlocks, calculateCodeScore, isCodeAligned } from './code'; 6 | export { analyzeProseWithClaude, parseProseAnalysis } from './prose'; 7 | export { analyzeConfigFiles, analyzeConfigFile, parseYamlFile } from './config'; 8 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/05-add-section-old-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/06-delete-section-new-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/05-needs-review-extra-section/source/analysis.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Data Analysis 3 | --- 4 | 5 | # Data Analysis 6 | 7 | ## Loading Data 8 | 9 | How to load data from various sources. 10 | 11 | ## Cleaning Data 12 | 13 | Data cleaning techniques. 14 | 15 | ## Visualization 16 | 17 | Creating charts and graphs. 18 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/09-config-identical/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Identical _toc.yml configuration", 3 | "configFiles": { 4 | "_toc.yml": { 5 | "status": "identical", 6 | "source": { "entries": 3 }, 7 | "target": { "entries": 3 }, 8 | "comparison": { "identical": true } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/source/diverged.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Diverged Chapter 3 | --- 4 | 5 | # Diverged Chapter 6 | 7 | ## Part One 8 | 9 | Content for part one. 10 | 11 | ## Part Two 12 | 13 | Content for part two. 14 | 15 | ## Part Three 16 | 17 | Content for part three. 18 | 19 | ## Part Four 20 | 21 | Content for part four. 22 | -------------------------------------------------------------------------------- /tool-onboarding/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | package-lock.json 4 | 5 | # Build output 6 | dist/ 7 | 8 | # Reports (except examples) 9 | reports/*.md 10 | !reports/README.md 11 | !reports/test-simple.md 12 | !reports/test-formatted.md 13 | 14 | # macOS 15 | .DS_Store 16 | 17 | # Editor 18 | .vscode/ 19 | .idea/ 20 | *.swp 21 | *.swo 22 | *~ 23 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/02-title-change-current-zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | heading-map: 7 | Supply and Demand: 供给与需求 8 | Economic Models: 经济模型 9 | --- 10 | 11 | # 经济学讲座 12 | 13 | 这是介绍段落。 14 | 15 | ## 供给与需求 16 | 17 | 供给和需求是经济学的基本概念。 18 | 19 | ## 经济模型 20 | 21 | 经济模型帮助我们理解复杂的系统。 22 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/03-section-content-current-zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | heading-map: 7 | Supply and Demand: 供给与需求 8 | Economic Models: 经济模型 9 | --- 10 | 11 | # 经济学讲座 12 | 13 | 这是介绍段落。 14 | 15 | ## 供给与需求 16 | 17 | 供给和需求是经济学的基本概念。 18 | 19 | ## 经济模型 20 | 21 | 经济模型帮助我们理解复杂的系统。 22 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/06-delete-section-current-zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | heading-map: 7 | Supply and Demand: 供给与需求 8 | Economic Models: 经济模型 9 | --- 10 | 11 | # 经济学讲座 12 | 13 | 这是介绍段落。 14 | 15 | ## 供给与需求 16 | 17 | 供给和需求是经济学的基本概念。 18 | 19 | ## 经济模型 20 | 21 | 经济模型帮助我们理解复杂的系统。 22 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/08-multi-element-current-zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | heading-map: 7 | Supply and Demand: 供给与需求 8 | Economic Models: 经济模型 9 | --- 10 | 11 | # 经济学讲座 12 | 13 | 这是介绍段落。 14 | 15 | ## 供给与需求 16 | 17 | 供给和需求是经济学的基本概念。 18 | 19 | ## 经济模型 20 | 21 | 经济模型帮助我们理解复杂的系统。 22 | -------------------------------------------------------------------------------- /tool-alignment/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | roots: ['/src'], 5 | testMatch: ['**/__tests__/**/*.test.ts'], 6 | moduleFileExtensions: ['ts', 'js', 'json'], 7 | collectCoverageFrom: ['src/**/*.ts', '!src/**/__tests__/**'], 8 | coverageDirectory: 'coverage', 9 | verbose: true, 10 | }; 11 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/06-diverged-major/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Major divergence - 6 sections in source, only 2 in target (<50% ratio)", 3 | "files": { 4 | "guide.md": { 5 | "status": "diverged", 6 | "source": { "sections": 6, "subsections": 0 }, 7 | "target": { "sections": 2, "subsections": 0 }, 8 | "comparison": { "sectionMatch": false } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/02-title-change-old-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/05-add-section-new-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/06-delete-section-old-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/08-multi-element-old-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/03-section-content-old-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/02-title-change-new-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # UPDATED Economics Lecture Title 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/03-likely-aligned/target/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 编程指南 3 | --- 4 | 5 | # 编程指南 6 | 7 | ## 简介 8 | 9 | 欢迎阅读编程指南。 10 | 11 | ## 变量 12 | 13 | 变量用于存储数据值。 14 | 15 | ```python 16 | x = 10 17 | y = "hello" 18 | ``` 19 | 20 | ## 函数 21 | 22 | 函数是可重用的代码块。 23 | 24 | ```python 25 | def greet(name): 26 | return f"你好,{name}" 27 | ``` 28 | 29 | 这是一个额外的例子: 30 | 31 | ```python 32 | # 额外的示例代码 33 | print("示范") 34 | ``` 35 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/10-config-diverged/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Diverged _toc.yml - different chapter counts", 3 | "configFiles": { 4 | "_toc.yml": { 5 | "status": "diverged", 6 | "source": { "entries": 5 }, 7 | "target": { "entries": 2 }, 8 | "comparison": { "identical": false, "structureMatch": false }, 9 | "issues": ["Entry count: source=5, target=2"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/04-section-reorder-current-zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | heading-map: 7 | Supply and Demand: 供给与需求 8 | Economic Models: 经济模型 9 | Market Equilibrium: 市场均衡 10 | --- 11 | 12 | # 经济学讲座 13 | 14 | 这是介绍段落。 15 | 16 | ## 供给与需求 17 | 18 | 供给和需求是经济学的基本概念。 19 | 20 | ## 经济模型 21 | 22 | 经济模型帮助我们理解复杂的系统。 23 | 24 | ## 市场均衡 25 | 26 | 当供给等于需求时,市场达到均衡。 27 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/01-aligned-perfect/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Perfect alignment - identical structure, no heading-map", 3 | "files": { 4 | "intro.md": { 5 | "status": "aligned", 6 | "source": { "sections": 2, "subsections": 0 }, 7 | "target": { "sections": 2, "subsections": 0, "hasHeadingMap": false }, 8 | "comparison": { "structureScore": 100, "sectionMatch": true } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tool-onboarding/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | roots: ['/src'], 5 | testMatch: ['**/__tests__/**/*.test.ts'], 6 | moduleFileExtensions: ['ts', 'js', 'json'], 7 | collectCoverageFrom: [ 8 | 'src/**/*.ts', 9 | '!src/**/*.d.ts', 10 | '!src/__tests__/**', 11 | '!src/index.ts' 12 | ], 13 | coverageDirectory: 'coverage', 14 | verbose: true 15 | }; 16 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/07-subsection-change-current-zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | heading-map: 7 | Supply and Demand: 供给与需求 8 | Market Equilibrium: 市场均衡 9 | Economic Models: 经济模型 10 | --- 11 | 12 | # 经济学讲座 13 | 14 | 这是介绍段落。 15 | 16 | ## 供给与需求 17 | 18 | 供给和需求是经济学的基本概念。 19 | 20 | ### 市场均衡 21 | 22 | 当供给等于需求时,市场达到均衡。 23 | 24 | ## 经济模型 25 | 26 | 经济模型帮助我们理解复杂的系统。 27 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/02-aligned-with-heading-map/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Perfect alignment with heading-map in target frontmatter", 3 | "files": { 4 | "intro.md": { 5 | "status": "aligned", 6 | "source": { "sections": 2, "subsections": 0 }, 7 | "target": { "sections": 2, "subsections": 0, "hasHeadingMap": true }, 8 | "comparison": { "structureScore": 100, "sectionMatch": true } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/03-section-content-new-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are UPDATED fundamental concepts that govern market behavior in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/01-intro-change-current-zh.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | heading-map: 7 | "Supply and Demand": "供给与需求" 8 | "Market Equilibrium": "市场均衡" 9 | "Economic Models": "经济模型" 10 | --- 11 | 12 | # 经济学讲座 13 | 14 | 这是原始的介绍段落,解释了经济概念。 15 | 16 | ## 供给与需求 17 | 18 | 供给和需求是经济学的基本概念。 19 | 20 | ### 市场均衡 21 | 22 | 当供给等于需求时出现市场均衡。 23 | 24 | ## 经济模型 25 | 26 | 经济模型帮助我们理解复杂的系统。 27 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/04-needs-review-missing-section/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Target is missing 1 section (Price Elasticity)", 3 | "files": { 4 | "economics.md": { 5 | "status": "needs-review", 6 | "source": { "sections": 5, "subsections": 0 }, 7 | "target": { "sections": 4, "subsections": 0 }, 8 | "comparison": { "sectionMatch": false }, 9 | "issues": ["Target is missing 1 section(s)"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/05-needs-review-extra-section/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Target has 1 extra section (localization content)", 3 | "files": { 4 | "analysis.md": { 5 | "status": "needs-review", 6 | "source": { "sections": 3, "subsections": 0 }, 7 | "target": { "sections": 4, "subsections": 0 }, 8 | "comparison": { "sectionMatch": false }, 9 | "issues": ["Target has 1 extra section(s)"] 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/12-code-math-blocks/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Tests code block and math block counting", 3 | "files": { 4 | "computing.md": { 5 | "status": "aligned", 6 | "source": { "sections": 3, "codeBlocks": 3, "mathBlocks": 2 }, 7 | "target": { "sections": 3, "codeBlocks": 3, "mathBlocks": 2 }, 8 | "comparison": { "structureScore": 100, "codeBlockMatch": true, "mathBlockMatch": true } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tool-test-action-on-github/evaluate/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "esModuleInterop": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "outDir": "dist", 10 | "rootDir": "src", 11 | "declaration": true, 12 | "resolveJsonModule": true 13 | }, 14 | "include": ["src/**/*"], 15 | "exclude": ["node_modules", "dist"] 16 | } 17 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/11-subsections-nested/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Deep nesting with ##, ###, ####, ##### headings", 3 | "files": { 4 | "linear-algebra.md": { 5 | "status": "aligned", 6 | "source": { "sections": 2, "subsections": 8 }, 7 | "target": { "sections": 2, "subsections": 8, "hasHeadingMap": true }, 8 | "comparison": { "structureScore": 100, "sectionMatch": true, "subsectionMatch": true } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/03-likely-aligned/source/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Programming Guide 3 | --- 4 | 5 | # Programming Guide 6 | 7 | ## Introduction 8 | 9 | Welcome to the programming guide. 10 | 11 | ## Variables 12 | 13 | Variables store data values. 14 | 15 | ```python 16 | x = 10 17 | y = "hello" 18 | ``` 19 | 20 | ## Functions 21 | 22 | Functions are reusable blocks of code. 23 | 24 | ```python 25 | def greet(name): 26 | return f"Hello, {name}" 27 | ``` 28 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/06-diverged-major/source/guide.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Complete Guide 3 | --- 4 | 5 | # Complete Guide 6 | 7 | ## Chapter One 8 | 9 | Introduction to the topic. 10 | 11 | ## Chapter Two 12 | 13 | Building on the basics. 14 | 15 | ## Chapter Three 16 | 17 | Advanced concepts. 18 | 19 | ## Chapter Four 20 | 21 | Practical applications. 22 | 23 | ## Chapter Five 24 | 25 | Case studies. 26 | 27 | ## Chapter Six 28 | 29 | Summary and conclusion. 30 | -------------------------------------------------------------------------------- /dist/diff-detector.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"diff-detector.d.ts","sourceRoot":"","sources":["../src/diff-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAW,aAAa,EAAE,MAAM,SAAS,CAAC;AAGjD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,KAAK,CAAU;gBAEX,KAAK,GAAE,OAAe;IAKlC,OAAO,CAAC,GAAG;IAMX;;;OAGG;IACG,oBAAoB,CACxB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,EAAE,CAAC;IAkH3B;;;;;;;OAOG;IACH,OAAO,CAAC,aAAa;IAMrB;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAwB5B"} -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/03-likely-aligned/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Likely aligned - same sections but different code block count", 3 | "files": { 4 | "guide.md": { 5 | "status": "likely-aligned", 6 | "source": { "sections": 3, "subsections": 0, "codeBlocks": 2 }, 7 | "target": { "sections": 3, "subsections": 0, "codeBlocks": 3 }, 8 | "comparison": { "structureScore": 85, "sectionMatch": true, "codeBlockMatch": false } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": [ 4 | "eslint:recommended", 5 | "plugin:@typescript-eslint/recommended" 6 | ], 7 | "parserOptions": { 8 | "ecmaVersion": 2020, 9 | "sourceType": "module" 10 | }, 11 | "rules": { 12 | "@typescript-eslint/no-explicit-any": "warn", 13 | "@typescript-eslint/explicit-function-return-type": "off", 14 | "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /dist/types.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Types and interfaces for the translation sync action 4 | * 5 | * This action uses a SECTION-BASED approach: 6 | * - Documents are parsed into sections based on ## headings 7 | * - Changes are detected at the section level 8 | * - Translations are performed on entire sections with full context 9 | * - Documents are reconstructed from translated sections 10 | */ 11 | Object.defineProperty(exports, "__esModule", { value: true }); 12 | //# sourceMappingURL=types.js.map -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/04-section-reorder-new-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Economic Models 13 | 14 | Economic models help us understand complex systems. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are fundamental concepts in economics. 19 | 20 | ## Market Equilibrium 21 | 22 | Markets reach equilibrium when supply equals demand. 23 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/04-section-reorder-old-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | 20 | ## Market Equilibrium 21 | 22 | Markets reach equilibrium when supply equals demand. 23 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/08-extra-file/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "One file exists only in target (localization content)", 3 | "files": { 4 | "main.md": { 5 | "status": "aligned", 6 | "source": { "sections": 1 }, 7 | "target": { "sections": 1 } 8 | }, 9 | "local-guide.md": { 10 | "status": "extra", 11 | "source": null, 12 | "target": { "sections": 2 }, 13 | "issues": ["File exists only in target repository (localization?)"] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/07-subsection-change-old-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ### Market Equilibrium 17 | 18 | Markets reach equilibrium when supply equals demand. 19 | 20 | ## Economic Models 21 | 22 | Economic models help us understand complex systems. 23 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/07-missing-file/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "One file exists in source but not in target (needs translation)", 3 | "files": { 4 | "existing.md": { 5 | "status": "aligned", 6 | "source": { "sections": 1 }, 7 | "target": { "sections": 1 } 8 | }, 9 | "new-chapter.md": { 10 | "status": "missing", 11 | "source": { "sections": 2 }, 12 | "target": null, 13 | "issues": ["File does not exist in target repository"] 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/04-needs-review-missing-section/source/economics.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Economics Basics 3 | --- 4 | 5 | # Economics Basics 6 | 7 | ## Supply and Demand 8 | 9 | The fundamental concepts of supply and demand. 10 | 11 | ## Market Equilibrium 12 | 13 | How markets reach equilibrium. 14 | 15 | ## Price Elasticity 16 | 17 | Understanding how prices respond to changes. 18 | 19 | ## Consumer Behavior 20 | 21 | How consumers make decisions. 22 | 23 | ## Summary 24 | 25 | Chapter summary and key takeaways. 26 | -------------------------------------------------------------------------------- /tool-onboarding/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["ES2020"], 6 | "outDir": "./dist", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "resolveJsonModule": true, 13 | "declaration": true, 14 | "sourceMap": true 15 | }, 16 | "include": ["src/**/*"], 17 | "exclude": ["node_modules", "dist", "**/*.test.ts"] 18 | } 19 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/08-multi-element-new-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # UPDATED Economics Lecture 9 | 10 | This is the UPDATED introduction paragraph with new content. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are UPDATED fundamental concepts in economics. 15 | 16 | ## Economic Models 17 | 18 | Economic models help us understand complex systems. 19 | 20 | ## Market Analysis 21 | 22 | NEWLY ADDED section about market analysis. 23 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/01-intro-change-old-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the original introduction paragraph explaining economic concepts. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ### Market Equilibrium 17 | 18 | Market equilibrium occurs where supply equals demand. 19 | 20 | ## Economic Models 21 | 22 | Economic models help us understand complex systems. 23 | -------------------------------------------------------------------------------- /dist/inputs.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"inputs.d.ts","sourceRoot":"","sources":["../src/inputs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA+BrD;;GAEG;AACH,wBAAgB,OAAO,IAAI,MAAM,GAAG,QAAQ,CAS3C;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,YAAY,CAuDxC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAwC9C;AAED;;;GAGG;AAEH,wBAAgB,eAAe,CAAC,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAuC3H;AAED;;;GAGG;AAEH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,GAAG,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAcxE"} -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/01-intro-change-new-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the UPDATED introduction paragraph with different wording about economic concepts. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ### Market Equilibrium 17 | 18 | Market equilibrium occurs where supply equals demand. 19 | 20 | ## Economic Models 21 | 22 | Economic models help us understand complex systems. 23 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/07-subsection-change-new-en.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | --- 7 | 8 | # Economics Lecture 9 | 10 | This is the introduction paragraph. 11 | 12 | ## Supply and Demand 13 | 14 | Supply and demand are fundamental concepts in economics. 15 | 16 | ### Market Equilibrium 17 | 18 | Markets reach equilibrium when supply equals demand. UPDATED: This is a key concept in microeconomics. 19 | 20 | ## Economic Models 21 | 22 | Economic models help us understand complex systems. 23 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/12-code-math-blocks/target/computing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 科学计算 3 | --- 4 | 5 | # 科学计算 6 | 7 | ## 代码示例 8 | 9 | 以下是一些代码示例。 10 | 11 | ```python 12 | import numpy as np 13 | x = np.array([1, 2, 3]) 14 | ``` 15 | 16 | 更多解释。 17 | 18 | ```python 19 | import pandas as pd 20 | df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]}) 21 | ``` 22 | 23 | ## 数学基础 24 | 25 | 该领域的关键方程。 26 | 27 | $$ 28 | E = mc^2 29 | $$ 30 | 31 | 上面是著名的方程。 32 | 33 | $$ 34 | \int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2} 35 | $$ 36 | 37 | ## 总结 38 | 39 | 总结概念。 40 | 41 | ```python 42 | print("Done!") 43 | ``` 44 | -------------------------------------------------------------------------------- /dist/translator.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"translator.d.ts","sourceRoot":"","sources":["../src/translator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,OAAO,EAAY,yBAAyB,EAAE,wBAAwB,EAAE,8BAA8B,EAAE,MAAM,SAAS,CAAC;AAmFxH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAU;gBAEX,MAAM,EAAE,MAAM,EAAE,KAAK,GAAE,MAAqC,EAAE,KAAK,GAAE,OAAe;IAMhG,OAAO,CAAC,GAAG;IAMX;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAe7F;;;OAGG;YACW,sBAAsB;IA+EpC;;;OAGG;YACW,mBAAmB;IAoEjC;;OAEG;IACG,qBAAqB,CAAC,OAAO,EAAE,8BAA8B,GAAG,OAAO,CAAC,wBAAwB,CAAC;IAuFvG;;OAEG;IACH,OAAO,CAAC,cAAc;CAiBvB"} -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["ES2020"], 6 | "outDir": "./dist", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "resolveJsonModule": true, 13 | "declaration": true, 14 | "declarationMap": true, 15 | "sourceMap": true, 16 | "moduleResolution": "node", 17 | "types": ["node", "jest"] 18 | }, 19 | "include": ["src/**/*"], 20 | "exclude": ["node_modules", "dist", "**/*.test.ts"] 21 | } 22 | -------------------------------------------------------------------------------- /dist/language-config.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"language-config.d.ts","sourceRoot":"","sources":["../src/language-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAgC3D,CAAC;AAEF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,CAOtE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAMlE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAS/D"} -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/11-subsections-nested/target/linear-algebra.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 线性代数 3 | heading-map: 4 | vector-spaces: "向量空间" 5 | definition: "定义" 6 | axioms: "公理" 7 | closure-property: "闭包性质" 8 | examples: "例子" 9 | matrix-operations: "矩阵运算" 10 | addition: "加法" 11 | multiplication: "乘法" 12 | properties: "性质" 13 | --- 14 | 15 | # 线性代数 16 | 17 | ## 向量空间 18 | 19 | 向量空间简介。 20 | 21 | ### 定义 22 | 23 | 向量空间是一个集合V及其运算。 24 | 25 | #### 公理 26 | 27 | 向量空间的公理。 28 | 29 | ##### 闭包性质 30 | 31 | 向量加法是封闭的。 32 | 33 | ### 例子 34 | 35 | 向量空间的例子。 36 | 37 | ## 矩阵运算 38 | 39 | 矩阵操作。 40 | 41 | ### 加法 42 | 43 | 矩阵加法说明。 44 | 45 | ### 乘法 46 | 47 | 矩阵乘法说明。 48 | 49 | #### 性质 50 | 51 | 矩阵乘法的性质。 52 | -------------------------------------------------------------------------------- /tool-alignment/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["ES2020"], 6 | "outDir": "./dist", 7 | "rootDir": "..", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "resolveJsonModule": true, 13 | "declaration": true, 14 | "declarationMap": true, 15 | "sourceMap": true 16 | }, 17 | "include": [ 18 | "src/**/*", 19 | "../src/parser.ts", 20 | "../src/heading-map.ts", 21 | "../src/types.ts" 22 | ], 23 | "exclude": [ 24 | "node_modules", 25 | "dist", 26 | "../src/__tests__" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/base-minimal-zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | heading-map: 11 | Introduction to Economics: 经济学导论 12 | Supply and Demand: 供给与需求 13 | Economic Models: 经济模型 14 | --- 15 | 16 | # 经济学导论 17 | 18 | 本文档提供了经济学原理的基本介绍。我们将探讨构成经济分析基础的基本概念。 19 | 20 | ## 供给与需求 21 | 22 | 供给和需求是经济学中最基本的概念。供给曲线显示生产者愿意以不同价格出售多少商品,而需求曲线显示消费者愿意购买多少商品。 23 | 24 | 当市场处于均衡状态时,供给量等于需求量。这个均衡价格平衡了买家和卖家的利益。 25 | 26 | ## 经济模型 27 | 28 | 经济模型是经济过程的简化表示。它们通过关注最重要的关系来帮助经济学家理解复杂系统。 29 | 30 | 模型做出假设以简化现实。虽然没有模型是完美的,但好的模型可以提供关于经济如何运作的宝贵见解。 31 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/14-code-integrity/target/code-integrity.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 代码完整性测试 3 | --- 4 | 5 | # 代码完整性测试 6 | 7 | ## 基本 Python 8 | 9 | 简单的 Python 代码应该保持不变: 10 | 11 | ```python 12 | import numpy as np 13 | x = np.array([1, 2, 3]) 14 | print(x) 15 | ``` 16 | 17 | ## 带注释 18 | 19 | 带注释的代码可能在翻译中被删除: 20 | 21 | ```python 22 | # 这是一个注释 23 | import pandas as pd 24 | # 创建一个数据框 25 | df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]}) 26 | print(df) 27 | ``` 28 | 29 | ## JavaScript 示例 30 | 31 | 多语言支持: 32 | 33 | ```javascript 34 | // JavaScript 注释 35 | const x = [1, 2, 3]; 36 | console.log(x); 37 | ``` 38 | 39 | ## 修改的代码 40 | 41 | 此代码在目标中将有所不同: 42 | 43 | ```python 44 | modified_function() 45 | y = 2 46 | ``` 47 | -------------------------------------------------------------------------------- /dist/parser.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAEtE,qBAAa,UAAU;IACrB;;;;OAIG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAsI/E;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IASzB;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAarE;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS;IAI9E;;;OAGG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAYlG;;;;;;;;;OASG;IACG,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAkE9F"} -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/11-subsections-nested/source/linear-algebra.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Linear Algebra 3 | --- 4 | 5 | # Linear Algebra 6 | 7 | ## Vector Spaces 8 | 9 | Introduction to vector spaces. 10 | 11 | ### Definition 12 | 13 | A vector space is a set V together with operations. 14 | 15 | #### Axioms 16 | 17 | The axioms of a vector space. 18 | 19 | ##### Closure Property 20 | 21 | Vector addition is closed. 22 | 23 | ### Examples 24 | 25 | Examples of vector spaces. 26 | 27 | ## Matrix Operations 28 | 29 | Working with matrices. 30 | 31 | ### Addition 32 | 33 | Matrix addition explained. 34 | 35 | ### Multiplication 36 | 37 | Matrix multiplication explained. 38 | 39 | #### Properties 40 | 41 | Properties of matrix multiplication. 42 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/12-code-math-blocks/source/computing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Scientific Computing 3 | --- 4 | 5 | # Scientific Computing 6 | 7 | ## Code Examples 8 | 9 | Here are some code examples. 10 | 11 | ```python 12 | import numpy as np 13 | x = np.array([1, 2, 3]) 14 | ``` 15 | 16 | More explanation here. 17 | 18 | ```python 19 | import pandas as pd 20 | df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]}) 21 | ``` 22 | 23 | ## Mathematical Foundations 24 | 25 | Key equations in this field. 26 | 27 | $$ 28 | E = mc^2 29 | $$ 30 | 31 | The famous equation above. 32 | 33 | $$ 34 | \int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2} 35 | $$ 36 | 37 | ## Summary 38 | 39 | Wrapping up the concepts. 40 | 41 | ```python 42 | print("Done!") 43 | ``` 44 | -------------------------------------------------------------------------------- /dist/heading-map.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"heading-map.d.ts","sourceRoot":"","sources":["../src/heading-map.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC;;;GAGG;AACH,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE7C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CA0B7D;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,UAAU,EACvB,cAAc,EAAE,OAAO,EAAE,EACzB,cAAc,EAAE,OAAO,EAAE,EACzB,YAAY,CAAC,EAAE,MAAM,GACpB,UAAU,CA+EZ;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAgB3D;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAepB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,UAAU,GACrB,MAAM,CA2CR"} -------------------------------------------------------------------------------- /tool-test-action-on-github/evaluate/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "evaluate-translation", 3 | "version": "1.0.0", 4 | "description": "Evaluate translation quality from test-action-on-github using Claude Opus 4.5", 5 | "type": "module", 6 | "main": "dist/evaluate.js", 7 | "scripts": { 8 | "build": "tsc", 9 | "test": "tsx src/test-changed-sections.ts", 10 | "evaluate": "tsx src/evaluate.ts", 11 | "evaluate:post": "tsx src/evaluate.ts --post-reviews" 12 | }, 13 | "dependencies": { 14 | "@anthropic-ai/sdk": "^0.39.0", 15 | "@octokit/rest": "^21.0.0", 16 | "chalk": "^5.3.0", 17 | "commander": "^12.0.0" 18 | }, 19 | "devDependencies": { 20 | "@types/node": "^20.10.0", 21 | "tsx": "^4.7.0", 22 | "typescript": "^5.3.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tool-onboarding/reports/lecture-python-intro↔lecture-intro.zh-cn/summary.md: -------------------------------------------------------------------------------- 1 | # Translation Alignment Report 2 | 3 | | Property | Value | 4 | |----------|-------| 5 | | Source | `lecture-python-intro` | 6 | | Target | `lecture-intro.zh-cn` | 7 | | Generated | 2025-12-19 | 8 | | Files Analyzed | 1 | 9 | 10 | ## Overview 11 | 12 | | Status | Count | Percentage | 13 | |--------|-------|------------| 14 | | ✅ Aligned | 0 | 0% | 15 | | 📋 Review | 1 | 100% | 16 | 17 | ## Action Summary 18 | 19 | | Action | Count | 20 | |--------|-------| 21 | | SYNC | 1 | 22 | | BACKPORT | 8 | 23 | | ACCEPT | 0 | 24 | | MANUAL | 2 | 25 | 26 | ## Files 27 | 28 | | File | Status | Direction | Actions | 29 | |------|--------|-----------|---------| 30 | | [cagan_adaptive.md](cagan_adaptive.md) | ⚠️ review | ← | SYNC: 1, BACKPORT: 8, MANUAL: 2 | 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | 3 | # Build output - Keep dist/index.js for GitHub Actions (main action) 4 | dist/node_modules/ 5 | dist/licenses.txt 6 | 7 | # Tool build outputs (standalone tools don't need committed builds) 8 | tool-bulk-translator/dist/ 9 | tool-test-action-on-github/evaluate/dist/ 10 | 11 | *.log 12 | .env 13 | .DS_Store 14 | coverage/ 15 | *.test.ts.snap 16 | .vscode/ 17 | .idea/ 18 | 19 | # TypeScript build info 20 | *.tsbuildinfo 21 | 22 | # Temporary files 23 | *.tmp 24 | .cache/ 25 | 26 | # Test repositories (cloned locally for testing) 27 | test-translation-sync/ 28 | test-translation-sync.zh-cn/ 29 | tool-test-action-on-github/test-translation-sync/ 30 | tool-test-action-on-github/test-translation-sync.zh-cn/ 31 | 32 | # Generated status reports 33 | tool-alignment/status/ 34 | tool-alignment/reports/ 35 | -------------------------------------------------------------------------------- /docs/presentations/diagrams/workflow.mmd: -------------------------------------------------------------------------------- 1 | graph LR 2 | A[PR Merged
English] --> B[Detect
Changed Files] 3 | B --> C[Parse into
Sections] 4 | C --> D{File
Type?} 5 | 6 | D -->|Existing| E[Diff Sections
Match to Target] 7 | D -->|New| F[Full
Translation] 8 | D -->|Deleted| G[Remove from
Target] 9 | 10 | E --> H[Claude AI
Translates] 11 | F --> H 12 | 13 | H --> I[Reconstruct
Document] 14 | I --> J[Create PR in
Target Repo] 15 | G --> J 16 | 17 | style A fill:#2E86AB,stroke:#1a5a7a,color:#fff,stroke-width:2px 18 | style H fill:#2E86AB,stroke:#1a5a7a,color:#fff,stroke-width:2px 19 | style J fill:#2E86AB,stroke:#1a5a7a,color:#fff,stroke-width:2px 20 | style D fill:#f0f4f8,stroke:#2E86AB,color:#1a1a1a,stroke-width:2px 21 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | testEnvironment: 'node', 4 | roots: ['/src'], 5 | testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'], 6 | transform: { 7 | '^.+\\.ts$': 'ts-jest', 8 | }, 9 | collectCoverageFrom: [ 10 | 'src/**/*.ts', 11 | '!src/**/*.test.ts', 12 | '!src/**/*.d.ts', 13 | ], 14 | coverageDirectory: 'coverage', 15 | coverageReporters: ['text', 'lcov', 'html'], 16 | transformIgnorePatterns: [ 17 | 'node_modules/(?!(unified|remark-parse|remark-stringify|remark-directive|remark-math|remark-gfm|unist-util-visit|mdast-util-to-string|bail|is-plain-obj|trough|vfile|unist-.*|mdast-.*|micromark.*|decode-named-character-reference|character-entities)/)', 18 | ], 19 | moduleNameMapper: { 20 | '^(\\.{1,2}/.*)\\.js$': '$1', 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/intro-zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | format_version: 0.13 7 | jupytext_version: 1.16.1 8 | kernelspec: 9 | display_name: Python 3 (ipykernel) 10 | language: python 11 | name: python3 12 | --- 13 | 14 | # 定量经济学简介 15 | 16 | 本讲座系列使用Python介绍定量经济学。 17 | 18 | ## 入门 19 | 20 | 要开始学习定量经济学,您需要了解经济建模的基础知识。 21 | 22 | 我们将介绍供求、优化和均衡等基本概念。 23 | 24 | ## 数学示例 25 | 26 | 考虑一个简单的优化问题: 27 | 28 | $$ 29 | \max_{x} f(x) = -x^2 + 4x + 1 30 | $$ 31 | 32 | 可以使用微积分找到解。 33 | 34 | ## Python工具 35 | 36 | 我们使用几个Python库: 37 | 38 | ```python 39 | import numpy as np 40 | import matplotlib.pyplot as plt 41 | ``` 42 | 43 | 这些工具对于数值计算至关重要。 44 | 45 | ## 数据分析 46 | 47 | 经济数据分析需要理解统计学和概率论。 48 | 49 | 我们将探索真实世界的数据集并应用计量经济学方法。 50 | 51 | ## 结论 52 | 53 | 本简介为定量经济学的更高级主题奠定了基础。 54 | 55 | -------------------------------------------------------------------------------- /tool-bulk-translator/examples/translate-lectures.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Example: Bulk translate lecture-python to Chinese (Simplified) 3 | 4 | # Set your API keys (or export from environment) 5 | export ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-your-anthropic-api-key-here}" 6 | export GITHUB_TOKEN="${GITHUB_TOKEN:-your-github-token-here}" 7 | 8 | # Run bulk translation 9 | npm run translate -- \ 10 | --source-repo QuantEcon/lecture-python \ 11 | --target-folder lecture-python.zh-cn \ 12 | --source-language en \ 13 | --target-language zh-cn \ 14 | --docs-folder lectures/ \ 15 | --anthropic-api-key "$ANTHROPIC_API_KEY" \ 16 | --github-token "$GITHUB_TOKEN" \ 17 | --batch-delay 1000 18 | 19 | # After completion, you can: 20 | # 1. Review translations: cd lecture-python.zh-cn 21 | # 2. Build the book: jupyter-book build . 22 | # 3. Initialize git and push to GitHub 23 | -------------------------------------------------------------------------------- /tool-bulk-translator/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["ES2020"], 6 | "outDir": "./dist", 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "resolveJsonModule": true, 12 | "declaration": true, 13 | "declarationMap": true, 14 | "sourceMap": true 15 | }, 16 | "include": [ 17 | "src/**/*", 18 | "../src/translator.ts", 19 | "../src/parser.ts", 20 | "../src/heading-map.ts", 21 | "../src/types.ts", 22 | "../src/language-config.ts" 23 | ], 24 | "exclude": [ 25 | "node_modules", 26 | "dist", 27 | "../src/__tests__", 28 | "../src/index.ts", 29 | "../src/inputs.ts", 30 | "../src/diff-detector.ts", 31 | "../src/file-processor.ts" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/06-delete-section-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 19 | 20 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers. 21 | -------------------------------------------------------------------------------- /dist/reviewer.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"reviewer.d.ts","sourceRoot":"","sources":["../src/reviewer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAIL,YAAY,EACZ,cAAc,EAEf,MAAM,SAAS,CAAC;AA0EjB;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,MAAM,GAClB,cAAc,EAAE,CAuFlB;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,cAAc,CAAS;gBAG7B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,KAAK,GAAE,MAA6B,EACpC,cAAc,GAAE,MAAU;IAQ5B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;OAEG;YACW,aAAa;IA4E3B;;OAEG;IACG,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,EACtB,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,YAAY,CAAC;IAwMxB;;OAEG;YACW,mBAAmB;IA2JjC;;OAEG;YACW,YAAY;IA+H1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAsB7B;;OAEG;IACH,OAAO,CAAC,eAAe;IAyBvB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA0E7B;;OAEG;YACW,iBAAiB;CAyChC"} -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/14-code-integrity/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Code block integrity check scenarios", 3 | "scenarios": [ 4 | { 5 | "name": "Identical code", 6 | "blockIndex": 0, 7 | "expected": "identical" 8 | }, 9 | { 10 | "name": "Different comments only", 11 | "blockIndex": 1, 12 | "expected": "normalized-match" 13 | }, 14 | { 15 | "name": "JavaScript identical", 16 | "blockIndex": 2, 17 | "expected": "normalized-match" 18 | }, 19 | { 20 | "name": "Modified code", 21 | "blockIndex": 3, 22 | "expected": "modified" 23 | }, 24 | { 25 | "name": "Missing code block", 26 | "blockIndex": 4, 27 | "expected": "missing" 28 | } 29 | ], 30 | "expectedCounts": { 31 | "sourceBlocks": 5, 32 | "targetBlocks": 4, 33 | "matchedBlocks": 3, 34 | "modifiedBlocks": 1, 35 | "missingBlocks": 1, 36 | "extraBlocks": 0 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tool-onboarding/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tool-onboarding", 3 | "version": "1.0.0", 4 | "description": "Simple CLI tool to check translation alignment using Claude AI", 5 | "main": "dist/index.js", 6 | "bin": { 7 | "onboard": "./dist/index.js" 8 | }, 9 | "scripts": { 10 | "build": "tsc", 11 | "test": "jest", 12 | "test:watch": "jest --watch", 13 | "test:coverage": "jest --coverage", 14 | "onboard": "ts-node src/index.ts" 15 | }, 16 | "keywords": [ 17 | "translation", 18 | "onboarding", 19 | "claude", 20 | "ai" 21 | ], 22 | "author": "QuantEcon", 23 | "license": "MIT", 24 | "dependencies": { 25 | "@anthropic-ai/sdk": "^0.52.0", 26 | "chalk": "^4.1.2", 27 | "commander": "^11.1.0" 28 | }, 29 | "devDependencies": { 30 | "@types/jest": "^30.0.0", 31 | "@types/node": "^20.10.4", 32 | "jest": "^30.2.0", 33 | "ts-jest": "^29.4.6", 34 | "ts-node": "^10.9.2", 35 | "typescript": "^5.3.3" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/13-multi-file-mixed/expected.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Multiple files with mixed alignment status", 3 | "files": { 4 | "aligned.md": { 5 | "status": "aligned", 6 | "source": { "sections": 2 }, 7 | "target": { "sections": 2, "hasHeadingMap": true } 8 | }, 9 | "diverged.md": { 10 | "status": "diverged", 11 | "source": { "sections": 4 }, 12 | "target": { "sections": 1 } 13 | }, 14 | "new.md": { 15 | "status": "missing", 16 | "source": { "sections": 1 }, 17 | "target": null 18 | }, 19 | "extra.md": { 20 | "status": "extra", 21 | "source": null, 22 | "target": { "sections": 1 } 23 | } 24 | }, 25 | "configFiles": { 26 | "_toc.yml": { 27 | "status": "structure-match", 28 | "source": { "entries": 3 }, 29 | "target": { "entries": 3 } 30 | } 31 | }, 32 | "summary": { 33 | "aligned": 1, 34 | "diverged": 1, 35 | "missing": 1, 36 | "extra": 1 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/14-code-integrity/source/code-integrity.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Code Integrity Test 3 | --- 4 | 5 | # Code Integrity Test 6 | 7 | ## Basic Python 8 | 9 | Simple Python code that should be preserved: 10 | 11 | ```python 12 | import numpy as np 13 | x = np.array([1, 2, 3]) 14 | print(x) 15 | ``` 16 | 17 | ## With Comments 18 | 19 | Code with comments that might be stripped in translation: 20 | 21 | ```python 22 | # This is a comment 23 | import pandas as pd 24 | # Create a dataframe 25 | df = pd.DataFrame({'a': [1, 2], 'b': [3, 4]}) 26 | print(df) 27 | ``` 28 | 29 | ## JavaScript Example 30 | 31 | Multi-language support: 32 | 33 | ```javascript 34 | // JavaScript comment 35 | const x = [1, 2, 3]; 36 | console.log(x); 37 | ``` 38 | 39 | ## Modified Code 40 | 41 | This code will be different in target: 42 | 43 | ```python 44 | original_function() 45 | x = 1 46 | ``` 47 | 48 | ## Missing Code 49 | 50 | This code block will be missing in target: 51 | 52 | ```python 53 | missing_code = True 54 | ``` 55 | -------------------------------------------------------------------------------- /dist/inputs.d.ts: -------------------------------------------------------------------------------- 1 | import { ActionInputs, ReviewInputs } from './types'; 2 | /** 3 | * Get the action mode (sync or review) 4 | */ 5 | export declare function getMode(): 'sync' | 'review'; 6 | /** 7 | * Get and validate action inputs for SYNC mode 8 | */ 9 | export declare function getInputs(): ActionInputs; 10 | /** 11 | * Get and validate action inputs for REVIEW mode 12 | */ 13 | export declare function getReviewInputs(): ReviewInputs; 14 | /** 15 | * Validate that the event is a merged PR or test mode label (SYNC mode) 16 | * Note: workflow_dispatch is NOT supported - use test-translation label for manual testing 17 | */ 18 | export declare function validatePREvent(context: any, testMode: boolean): { 19 | merged: boolean; 20 | prNumber: number; 21 | isTestMode: boolean; 22 | }; 23 | /** 24 | * Validate that the event is a PR event (REVIEW mode) 25 | * Returns PR number for open PRs, or throws if not a PR event 26 | */ 27 | export declare function validateReviewPREvent(context: any): { 28 | prNumber: number; 29 | }; 30 | //# sourceMappingURL=inputs.d.ts.map -------------------------------------------------------------------------------- /tool-bulk-translator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bulk-translator", 3 | "version": "1.0.0", 4 | "description": "Bulk translation tool for bootstrapping new language repositories", 5 | "main": "dist/tool-bulk-translator/src/bulk-translate.js", 6 | "scripts": { 7 | "clean": "rm -rf dist", 8 | "build:ts": "tsc", 9 | "build:resources": "mkdir -p dist/resources && cp -r ../glossary dist/resources/", 10 | "build": "npm run clean && npm run build:ts && npm run build:resources", 11 | "translate": "npm run build && node dist/tool-bulk-translator/src/bulk-translate.js" 12 | }, 13 | "keywords": [ 14 | "translation", 15 | "bulk", 16 | "claude", 17 | "jupyter-book" 18 | ], 19 | "author": "QuantEcon", 20 | "license": "MIT", 21 | "dependencies": { 22 | "@anthropic-ai/sdk": "^0.27.0", 23 | "@octokit/rest": "^20.0.0", 24 | "commander": "^11.1.0", 25 | "js-yaml": "^4.1.0", 26 | "chalk": "^4.1.2", 27 | "ora": "^5.4.1" 28 | }, 29 | "devDependencies": { 30 | "@types/node": "^20.10.0", 31 | "@types/js-yaml": "^4.0.9", 32 | "typescript": "^5.3.2" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /dist/file-processor.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"file-processor.d.ts","sourceRoot":"","sources":["../src/file-processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAW,QAAQ,EAAE,MAAM,SAAS,CAAC;AAU5C,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,KAAK,CAAU;gBAEX,kBAAkB,EAAE,kBAAkB,EAAE,KAAK,GAAE,OAAe;IAO1E,OAAO,CAAC,GAAG;IAMX;;;;OAIG;IACG,mBAAmB,CACvB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,MAAM,CAAC;IA2UlB;;OAEG;YACW,mBAAmB;IAuCjC;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAkCjC;;OAEG;IACG,WAAW,CACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,MAAM,CAAC;IAiBlB;;;;OAIG;YACW,0BAA0B;IAqExC;;;OAGG;IACH,OAAO,CAAC,6BAA6B;IAwDrC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;;;;;;;;OASG;IACH,OAAO,CAAC,sBAAsB;IAoC9B;;;;;OAKG;IACH,OAAO,CAAC,wBAAwB;IAmBhC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAGnG"} -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/base-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 19 | 20 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers. 21 | 22 | ## Economic Models 23 | 24 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 25 | 26 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 27 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/02-title-change-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Principles of Economic Analysis 13 | 14 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 19 | 20 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers. 21 | 22 | ## Economic Models 23 | 24 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 25 | 26 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 27 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/16-pure-section-reorder-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 15 | 16 | ## Economic Models 17 | 18 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 19 | 20 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 21 | 22 | ## Supply and Demand 23 | 24 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 25 | 26 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers. 27 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/04-section-reorder-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 15 | 16 | ## Economic Models 17 | 18 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships and interactions. 19 | 20 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 21 | 22 | ## Supply and Demand 23 | 24 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 25 | 26 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers. 27 | -------------------------------------------------------------------------------- /tool-alignment/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tool-alignment", 3 | "version": "0.1.0", 4 | "description": "Alignment diagnostic tool for translation repositories", 5 | "main": "dist/tool-alignment/src/index.js", 6 | "scripts": { 7 | "clean": "rm -rf dist", 8 | "build:ts": "tsc", 9 | "build": "npm run clean && npm run build:ts", 10 | "cli": "npm run build && node dist/tool-alignment/src/index.js", 11 | "diagnose": "npm run build && node dist/tool-alignment/src/index.js diagnose", 12 | "triage": "npm run build && node dist/tool-alignment/src/index.js triage", 13 | "file": "npm run build && node dist/tool-alignment/src/index.js file", 14 | "test": "jest" 15 | }, 16 | "keywords": [ 17 | "translation", 18 | "alignment", 19 | "diagnostic", 20 | "jupyter-book" 21 | ], 22 | "author": "QuantEcon", 23 | "license": "MIT", 24 | "dependencies": { 25 | "@anthropic-ai/sdk": "^0.39.0", 26 | "commander": "^11.1.0", 27 | "js-yaml": "^4.1.0", 28 | "chalk": "^4.1.2" 29 | }, 30 | "devDependencies": { 31 | "@types/node": "^20.10.0", 32 | "@types/js-yaml": "^4.0.9", 33 | "@types/jest": "^29.5.10", 34 | "jest": "^29.7.0", 35 | "ts-jest": "^29.1.1", 36 | "typescript": "^5.3.2" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/01-intro-change-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a comprehensive introduction to economic principles with updated content and examples. We will explore fundamental concepts that form the foundation of modern economic analysis. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 19 | 20 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers. 21 | 22 | ## Economic Models 23 | 24 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 25 | 26 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 27 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/21-preamble-only-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | format_version: 0.13 7 | jupytext_version: 1.16.1 8 | kernelspec: 9 | display_name: Python 3 (ipykernel) 10 | language: python 11 | name: python3 12 | --- 13 | 14 | # Introduction to Economics 15 | 16 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 17 | 18 | ## Supply and Demand 19 | 20 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 21 | 22 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers. 23 | 24 | ## Economic Models 25 | 26 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 27 | 28 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 29 | 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "action-translation", 3 | "version": "0.7.0", 4 | "description": "GitHub Action to sync and review translations across repositories", 5 | "main": "dist/index.js", 6 | "scripts": { 7 | "build": "tsc && ncc build dist/index.js -o dist", 8 | "test": "jest", 9 | "lint": "eslint src/**/*.ts", 10 | "format": "prettier --write src/**/*.ts" 11 | }, 12 | "keywords": [ 13 | "github-action", 14 | "translation", 15 | "sync", 16 | "review", 17 | "myst", 18 | "markdown" 19 | ], 20 | "author": "QuantEcon", 21 | "license": "MIT", 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/QuantEcon/action-translation.git" 25 | }, 26 | "dependencies": { 27 | "@actions/core": "^1.10.1", 28 | "@actions/github": "^6.0.0", 29 | "@anthropic-ai/sdk": "^0.27.0", 30 | "js-yaml": "^4.1.0" 31 | }, 32 | "devDependencies": { 33 | "@types/jest": "^29.5.10", 34 | "@types/js-yaml": "^4.0.9", 35 | "@types/node": "^20.10.0", 36 | "@typescript-eslint/eslint-plugin": "^6.13.0", 37 | "@typescript-eslint/parser": "^6.13.0", 38 | "@vercel/ncc": "^0.38.1", 39 | "eslint": "^8.54.0", 40 | "jest": "^29.7.0", 41 | "prettier": "^3.1.0", 42 | "ts-jest": "^29.1.1", 43 | "typescript": "^5.3.2" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/intro-old.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | format_version: 0.13 7 | jupytext_version: 1.16.1 8 | kernelspec: 9 | display_name: Python 3 (ipykernel) 10 | language: python 11 | name: python3 12 | --- 13 | 14 | # Introduction to Quantitative Economics 15 | 16 | This lecture series provides an introduction to quantitative economics using Python. 17 | 18 | ## Getting Started 19 | 20 | To begin with quantitative economics, you need to understand the basics of economic modeling. 21 | 22 | We will cover fundamental concepts like supply and demand, optimization, and equilibrium. 23 | 24 | ## Mathematical Example 25 | 26 | Consider a simple optimization problem: 27 | 28 | $$ 29 | \max_{x} f(x) = -x^2 + 4x + 1 30 | $$ 31 | 32 | The solution can be found using calculus. 33 | 34 | ## Python Tools 35 | 36 | We use several Python libraries: 37 | 38 | ```python 39 | import numpy as np 40 | import matplotlib.pyplot as plt 41 | ``` 42 | 43 | These tools are essential for numerical computation. 44 | 45 | ## Data Analysis 46 | 47 | Economic data analysis requires understanding statistics and probability. 48 | 49 | We will explore real-world datasets and apply econometric methods. 50 | 51 | ## Conclusion 52 | 53 | This introduction sets the stage for more advanced topics in quantitative economics. 54 | 55 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/03-section-content-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are the cornerstone concepts in economics, forming the basis of market analysis. The supply curve illustrates producer behavior at various price points, showing how much they're willing to sell. Conversely, the demand curve represents consumer behavior and purchasing decisions. 19 | 20 | Market equilibrium occurs at the intersection of supply and demand curves. At this point, the quantity supplied equals the quantity demanded, and the market clears efficiently. This equilibrium price represents the market's natural balance. 21 | 22 | ## Economic Models 23 | 24 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 25 | 26 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 27 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/07-subsection-change-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 19 | 20 | ### Market Equilibrium 21 | 22 | Market equilibrium occurs when supply equals demand. At this critical point, the quantity that producers want to sell exactly matches what consumers want to buy. This equilibrium price represents a stable state where market forces are balanced, and there is no inherent pressure for prices to change. 23 | 24 | ## Economic Models 25 | 26 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 27 | 28 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 29 | -------------------------------------------------------------------------------- /docs/presentations/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Build script for Translation Sync Action presentation 3 | 4 | set -e 5 | 6 | echo "Building Translation Sync Action presentation..." 7 | 8 | # Navigate to presentations directory 9 | cd "$(dirname "$0")" 10 | 11 | # Step 1: Generate Mermaid diagrams as PNG 12 | echo "1. Generating Mermaid diagrams..." 13 | if command -v mmdc &> /dev/null; then 14 | mmdc -i diagrams/workflow.mmd -o diagrams/workflow.png -t neutral -b transparent 15 | echo " ✓ Generated diagrams/workflow.png" 16 | else 17 | echo " ⚠️ Mermaid CLI not found. Install with: npm install -g @mermaid-js/mermaid-cli" 18 | echo " Skipping diagram generation..." 19 | fi 20 | 21 | # Step 2: Build PDF with Marp 22 | echo "2. Building PDF presentation..." 23 | if command -v marp &> /dev/null; then 24 | marp action-translation-sync.md -o action-translation-sync.pdf --allow-local-files 25 | echo " ✓ Generated action-translation-sync.pdf" 26 | else 27 | echo " ⚠️ Marp CLI not found. Install with: npm install -g @marp-team/marp-cli" 28 | exit 1 29 | fi 30 | 31 | # Step 3: Build HTML (optional) 32 | echo "3. Building HTML presentation..." 33 | marp action-translation-sync.md -o action-translation-sync.html --allow-local-files 34 | echo " ✓ Generated action-translation-sync.html" 35 | 36 | echo "" 37 | echo "✅ Build complete!" 38 | echo " - action-translation-sync.pdf" 39 | echo " - action-translation-sync.html" 40 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/05-add-section-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a basic introduction to economic principles. We will explore fundamental concepts that form the foundation of economic analysis. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 19 | 20 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers. 21 | 22 | ## Economic Models 23 | 24 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 25 | 26 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 27 | 28 | ## Market Equilibrium 29 | 30 | Market equilibrium represents the state where supply equals demand. At this point, there is no tendency for the price to change, as the market has reached a stable state. Understanding equilibrium is crucial for analyzing market dynamics. 31 | -------------------------------------------------------------------------------- /dist/diff-detector.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Section-Based Diff Detection Engine 3 | * 4 | * Detects changes at the section level (## headings) rather than individual blocks. 5 | * This approach is much simpler and more reliable for translation workflows. 6 | * 7 | * Key principles: 8 | * - Sections are matched by position (most reliable for translations) 9 | * - Changes are: added section, modified section, deleted section 10 | * - No complex block matching or insertion point logic needed 11 | */ 12 | import { SectionChange } from './types'; 13 | export declare class DiffDetector { 14 | private parser; 15 | private debug; 16 | constructor(debug?: boolean); 17 | private log; 18 | /** 19 | * Detect section-level changes between old and new documents 20 | * Also detects preamble changes (title and intro before first ## section) 21 | */ 22 | detectSectionChanges(oldContent: string, newContent: string, filepath: string): Promise; 23 | /** 24 | * Check if two sections match (for position-based matching) 25 | * Sections match if they have the same ID (heading) 26 | * 27 | * Note: We used to check structural similarity (level + subsection count), 28 | * but this caused false matches when inserting new sections. 29 | * Now we require ID match for position-based matching. 30 | */ 31 | private sectionsMatch; 32 | /** 33 | * Check if section content has changed (including all nested subsections recursively) 34 | */ 35 | private sectionContentEqual; 36 | } 37 | //# sourceMappingURL=diff-detector.d.ts.map -------------------------------------------------------------------------------- /dist/language-config.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"language-config.js","sourceRoot":"","sources":["../src/language-config.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAyDH,8CAOC;AAMD,sDAMC;AAKD,sDAEC;AAKD,kDAGC;AAKD,oDASC;AA9FD;;;;;;;GAOG;AACU,QAAA,gBAAgB,GAAmC;IAC9D,OAAO,EAAE;QACP,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,sBAAsB;QAC5B,eAAe,EAAE;YACf,oGAAoG;SACrG;KACF;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,iBAAiB;QACvB,eAAe,EAAE;YACf,oFAAoF;YACpF,gEAAgE;YAChE,uEAAuE;SACxE;KACF;IACD,oDAAoD;IACpD,UAAU;IACV,gBAAgB;IAChB,sBAAsB;IACtB,uBAAuB;IACvB,sDAAsD;IACtD,OAAO;IACP,KAAK;IACL,UAAU;IACV,gBAAgB;IAChB,qBAAqB;IACrB,uBAAuB;IACvB,qFAAqF;IACrF,OAAO;IACP,KAAK;CACN,CAAC;AAEF;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,YAAoB;IACpD,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,wBAAgB,CAAC,UAAU,CAAC,IAAI;QACrC,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,YAAY;QAClB,eAAe,EAAE,EAAE;KACpB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,qBAAqB,CAAC,YAAoB;IACxD,MAAM,MAAM,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB;IACnC,OAAO,MAAM,CAAC,IAAI,CAAC,wBAAgB,CAAC,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,YAAoB;IACtD,MAAM,UAAU,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,UAAU,IAAI,wBAAgB,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,YAAoB;IACvD,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,qBAAqB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,IAAI,KAAK,CACb,iCAAiC,YAAY,KAAK;YAClD,wBAAwB,SAAS,IAAI;YACrC,0EAA0E,CAC3E,CAAC;IACJ,CAAC;AACH,CAAC"} -------------------------------------------------------------------------------- /dist/translator.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Section-Based Translation Service 3 | * 4 | * Uses Claude Sonnet 4.5 to translate sections of MyST Markdown documents. 5 | * 6 | * Two modes: 7 | * 1. UPDATE: Claude sees old English, new English, current translation → produces updated translation 8 | * 2. NEW: Claude sees new English → produces new translation 9 | * 10 | * For full documents (new files), translates the entire content in one pass. 11 | */ 12 | import { SectionTranslationRequest, SectionTranslationResult, FullDocumentTranslationRequest } from './types'; 13 | export declare class TranslationService { 14 | private client; 15 | private model; 16 | private debug; 17 | constructor(apiKey: string, model?: string, debug?: boolean); 18 | private log; 19 | /** 20 | * Translate a section (update or new) 21 | */ 22 | translateSection(request: SectionTranslationRequest): Promise; 23 | /** 24 | * Update existing section (mode='update') 25 | * Claude sees: old English, new English, current translation → produces updated translation 26 | */ 27 | private translateSectionUpdate; 28 | /** 29 | * Translate new section (mode='new') 30 | * Claude sees: English section → produces translation 31 | */ 32 | private translateNewSection; 33 | /** 34 | * Translate full document (for new files) 35 | */ 36 | translateFullDocument(request: FullDocumentTranslationRequest): Promise; 37 | /** 38 | * Format glossary for inclusion in prompt 39 | */ 40 | private formatGlossary; 41 | } 42 | //# sourceMappingURL=translator.d.ts.map -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/08-multi-element-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Comprehensive Introduction to Economic Principles 13 | 14 | This document provides an extensively updated introduction to modern economic principles. We will explore fundamental concepts that form the foundation of economic analysis, with new examples and contemporary applications. 15 | 16 | ## Supply and Demand Analysis 17 | 18 | Supply and demand are the cornerstone of economic theory. The supply curve demonstrates producer behavior across different price points, showing their willingness to sell at various levels. The demand curve represents consumer preferences and purchasing decisions across the price spectrum. 19 | 20 | Market equilibrium is achieved when these forces balance. At equilibrium, quantity supplied equals quantity demanded, creating market stability. This price point efficiently allocates resources between buyers and sellers. 21 | 22 | ## Economic Models 23 | 24 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships. 25 | 26 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works. 27 | 28 | ## Policy Applications 29 | 30 | Economic principles guide policy decisions at all levels of government. Understanding supply and demand helps policymakers evaluate the impact of taxes, subsidies, and regulations. These tools shape market outcomes and influence economic welfare. 31 | -------------------------------------------------------------------------------- /src/__tests__/fixtures/intro-new.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | format_version: 0.13 7 | jupytext_version: 1.16.1 8 | kernelspec: 9 | display_name: Python 3 (ipykernel) 10 | language: python 11 | name: python3 12 | --- 13 | 14 | # Introduction to Quantitative Economics 15 | 16 | This lecture series provides a comprehensive introduction to quantitative economics using Python and modern computational methods. 17 | 18 | ## Getting Started 19 | 20 | To begin with quantitative economics, you need to understand the basics of economic modeling. 21 | 22 | We will cover fundamental concepts like supply and demand, optimization, and equilibrium. 23 | 24 | ## Economic Models 25 | 26 | Economic models are simplified representations of economic processes. They help us understand complex systems by focusing on key relationships. 27 | 28 | We use both theoretical and empirical approaches to build and test these models. 29 | 30 | ## Mathematical Example 31 | 32 | Consider a simple optimization problem: 33 | 34 | $$ 35 | \max_{x} f(x) = -x^2 + 4x + 1 36 | $$ 37 | 38 | The solution is found by taking the derivative and setting it to zero. 39 | 40 | ## Python Tools 41 | 42 | We use several Python libraries: 43 | 44 | ```python 45 | import numpy as np 46 | import matplotlib.pyplot as plt 47 | import pandas as pd 48 | ``` 49 | 50 | These tools are essential for numerical computation and data analysis. 51 | 52 | ## Data Analysis 53 | 54 | Economic data analysis requires understanding statistics and probability. 55 | 56 | We will explore real-world datasets and apply econometric methods. 57 | 58 | ## Conclusion 59 | 60 | This introduction sets the stage for more advanced topics in quantitative economics. 61 | 62 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/19-multi-file-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Introduction to Economics 13 | 14 | This document provides a comprehensive introduction to economic principles. We will explore fundamental concepts that form the foundation of modern economic analysis and decision-making. 15 | 16 | ## Supply and Demand 17 | 18 | Supply and demand are the most fundamental concepts in economics. The supply curve shows how much producers are willing to sell at different prices, while the demand curve shows how much consumers are willing to buy. 19 | 20 | When markets are in equilibrium, the quantity supplied equals the quantity demanded. This equilibrium price balances the interests of buyers and sellers, creating market efficiency. 21 | 22 | ### Market Dynamics 23 | 24 | Market forces continuously adjust prices toward equilibrium. When prices are too high, surplus inventory builds up. When prices are too low, shortages occur. These imbalances create pressure for price adjustments. 25 | 26 | ## Economic Models 27 | 28 | Economic models are simplified representations of economic processes. They help economists understand complex systems by focusing on the most important relationships and interactions. 29 | 30 | Models make assumptions to simplify reality. While no model is perfect, good models provide valuable insights into how the economy works and help predict future outcomes. 31 | 32 | ## Policy Implications 33 | 34 | Understanding these fundamental concepts is crucial for designing effective economic policies. Policymakers must consider market mechanisms when implementing regulations or interventions. 35 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/24-empty-sections-minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Economic Theory Framework 13 | 14 | This document outlines a framework for economic analysis, with some sections serving as placeholders for future content. 15 | 16 | ## Microeconomics 17 | 18 | Microeconomics studies individual decision-making and market interactions at the level of firms and households. 19 | 20 | ## Macroeconomics 21 | 22 | ## International Economics 23 | 24 | International economics examines cross-border trade, finance, and policy coordination. 25 | 26 | ### Trade Theory 27 | 28 | ### Exchange Rates 29 | 30 | Exchange rate dynamics affect international competitiveness and capital flows. 31 | 32 | ### International Finance 33 | 34 | ## Econometrics 35 | 36 | Statistical methods for estimating economic relationships and testing hypotheses. 37 | 38 | ### Time Series Analysis 39 | 40 | ### Cross-Sectional Methods 41 | 42 | Cross-sectional analysis examines data from a single point in time across multiple entities. 43 | 44 | ### Panel Data Techniques 45 | 46 | ## Development Economics 47 | 48 | ## Behavioral Economics 49 | 50 | Behavioral economics incorporates psychological insights into economic models, explaining deviations from rational choice theory. 51 | 52 | ### Cognitive Biases 53 | 54 | ### Prospect Theory 55 | 56 | Prospect theory describes how people make decisions under risk, showing asymmetric responses to gains and losses. 57 | 58 | ### Applications 59 | 60 | ## Conclusion 61 | 62 | This framework provides a structure for organizing economic research and teaching. Empty sections indicate areas for future expansion. 63 | -------------------------------------------------------------------------------- /dist/language-config.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Language-specific configuration for translation prompts 3 | * 4 | * Each target language can have specific instructions that are appended to the translation prompts. 5 | * This allows for language-specific typography, punctuation, and stylistic rules. 6 | */ 7 | export interface LanguageConfig { 8 | /** Language code (e.g., 'zh-cn', 'ja', 'es') */ 9 | code: string; 10 | /** Language name in English */ 11 | name: string; 12 | /** Additional rules to append to translation prompts */ 13 | additionalRules: string[]; 14 | } 15 | /** 16 | * Language-specific configurations 17 | * 18 | * To add a new language: 19 | * 1. Add a new entry with the language code as the key 20 | * 2. Include any language-specific typography or punctuation rules 21 | * 3. The language will automatically be available for use 22 | */ 23 | export declare const LANGUAGE_CONFIGS: Record; 24 | /** 25 | * Get language-specific configuration 26 | * Returns empty rules array if language not configured 27 | */ 28 | export declare function getLanguageConfig(languageCode: string): LanguageConfig; 29 | /** 30 | * Format additional rules for inclusion in prompts 31 | * Returns empty string if no additional rules 32 | */ 33 | export declare function formatAdditionalRules(languageCode: string): string; 34 | /** 35 | * Get list of supported language codes 36 | */ 37 | export declare function getSupportedLanguages(): string[]; 38 | /** 39 | * Check if a language code is supported (has configuration) 40 | */ 41 | export declare function isLanguageSupported(languageCode: string): boolean; 42 | /** 43 | * Validate language code and throw descriptive error if not supported 44 | */ 45 | export declare function validateLanguageCode(languageCode: string): void; 46 | //# sourceMappingURL=language-config.d.ts.map -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/workflow-template.yml: -------------------------------------------------------------------------------- 1 | name: Translation Sync 2 | 3 | on: 4 | pull_request: 5 | types: [closed, labeled] 6 | 7 | jobs: 8 | sync-translation: 9 | # Run on merge (production) OR when test-translation label added (test mode) 10 | if: | 11 | (github.event.pull_request.merged == true) || 12 | (github.event.action == 'labeled' && github.event.label.name == 'test-translation') 13 | 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - name: Checkout action repository 18 | uses: actions/checkout@v4 19 | with: 20 | repository: QuantEcon/action-translation 21 | path: action 22 | 23 | - name: Setup Node.js 24 | uses: actions/setup-node@v4 25 | with: 26 | node-version: '20' 27 | 28 | - name: Install dependencies 29 | run: | 30 | cd action 31 | npm ci 32 | 33 | - name: Determine mode 34 | id: mode 35 | run: | 36 | if [[ "${{ github.event.pull_request.merged }}" == "true" ]]; then 37 | echo "mode=production" >> $GITHUB_OUTPUT 38 | echo "commit_sha=${{ github.event.pull_request.merge_commit_sha }}" >> $GITHUB_OUTPUT 39 | echo "🚀 Running in PRODUCTION mode (merged PR)" 40 | else 41 | echo "mode=test" >> $GITHUB_OUTPUT 42 | echo "commit_sha=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT 43 | echo "🧪 Running in TEST mode (test-translation label)" 44 | fi 45 | 46 | - name: Run translation sync 47 | uses: ./action 48 | with: 49 | mode: sync 50 | target-repo: ${{ github.repository }}.zh-cn 51 | target-language: zh-cn 52 | source-language: en 53 | docs-folder: '.' 54 | anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} 55 | github-token: ${{ secrets.QUANTECON_SERVICES_PAT }} 56 | test-mode: ${{ steps.mode.outputs.mode == 'test' }} 57 | -------------------------------------------------------------------------------- /dist/reviewer.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Translation Reviewer for GitHub Action Review Mode 3 | * 4 | * Provides AI-powered quality assessment of translation PRs. 5 | * Adapted from tool-test-action-on-github/evaluate/src/evaluator.ts 6 | */ 7 | import { ReviewResult, ChangedSection } from './types'; 8 | /** 9 | * Identify changed sections by comparing before and after content 10 | */ 11 | export declare function identifyChangedSections(sourceBefore: string, sourceAfter: string, targetBefore: string, targetAfter: string): ChangedSection[]; 12 | /** 13 | * Translation Reviewer class 14 | * Evaluates translation quality and posts review comments on PRs 15 | */ 16 | export declare class TranslationReviewer { 17 | private anthropic; 18 | private octokit; 19 | private model; 20 | private maxSuggestions; 21 | constructor(anthropicApiKey: string, githubToken: string, model?: string, maxSuggestions?: number); 22 | /** 23 | * Parse source PR number from translation PR body 24 | * Looks for: ### Source PR\n**[#123 - ... 25 | */ 26 | private parseSourcePRNumber; 27 | /** 28 | * Get source PR diff (English before/after) 29 | */ 30 | private getSourceDiff; 31 | /** 32 | * Review a translation PR 33 | */ 34 | reviewPR(prNumber: number, sourceRepo: string, targetOwner: string, targetRepo: string, docsFolder: string, glossaryTerms?: string, targetLanguage?: string): Promise; 35 | /** 36 | * Evaluate translation quality using Claude 37 | */ 38 | private evaluateTranslation; 39 | /** 40 | * Evaluate diff quality using Claude 41 | */ 42 | private evaluateDiff; 43 | /** 44 | * Format changed sections for the prompt 45 | */ 46 | private formatChangedSections; 47 | /** 48 | * Normalize issues to strings 49 | */ 50 | private normalizeIssues; 51 | /** 52 | * Generate review comment 53 | */ 54 | private generateReviewComment; 55 | /** 56 | * Post review comment on PR 57 | */ 58 | private postReviewComment; 59 | } 60 | //# sourceMappingURL=reviewer.d.ts.map -------------------------------------------------------------------------------- /dist/heading-map.d.ts: -------------------------------------------------------------------------------- 1 | import { Section } from './types'; 2 | /** 3 | * Path separator for hierarchical heading keys 4 | * Example: "Vector Spaces::Basic Properties::Applications in Economics" 5 | */ 6 | export declare const PATH_SEPARATOR = "::"; 7 | /** 8 | * Heading map for matching sections across languages 9 | * Maps English heading path → Translated heading text 10 | * 11 | * Path format: 12 | * - Top-level sections: "Section Name" 13 | * - Nested sections: "Parent::Child::Grandchild" 14 | * 15 | * This ensures uniqueness even when multiple sections share the same heading text. 16 | */ 17 | export type HeadingMap = Map; 18 | /** 19 | * Extract heading map from target document frontmatter 20 | */ 21 | export declare function extractHeadingMap(content: string): HeadingMap; 22 | /** 23 | * Update heading map with new translations 24 | * - Adds new English→Translation pairs for ALL headings (sections and subsections) 25 | * - Uses path-based keys (Parent::Child::Grandchild) for uniqueness 26 | * - Removes deleted sections 27 | * - Preserves existing mappings 28 | */ 29 | export declare function updateHeadingMap(existingMap: HeadingMap, sourceSections: Section[], targetSections: Section[], titleHeading?: string): HeadingMap; 30 | /** 31 | * Serialize heading map to YAML string for frontmatter 32 | */ 33 | export declare function serializeHeadingMap(map: HeadingMap): string; 34 | /** 35 | * Find target section by looking up heading path in map 36 | * Returns the target heading to search for, or undefined if not in map 37 | * 38 | * @param sourceHeading - The source heading text (e.g., "## Applications in Economics") 39 | * @param headingMap - The heading map 40 | * @param parentPath - The path of parent sections (e.g., "Vector Spaces::Basic Properties") 41 | */ 42 | export declare function lookupTargetHeading(sourceHeading: string, headingMap: HeadingMap, parentPath?: string): string | undefined; 43 | /** 44 | * Inject or update heading-map in frontmatter 45 | * Preserves all existing frontmatter fields 46 | */ 47 | export declare function injectHeadingMap(content: string, headingMap: HeadingMap): string; 48 | //# sourceMappingURL=heading-map.d.ts.map -------------------------------------------------------------------------------- /dist/parser.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * MyST Markdown Section Parser 3 | * 4 | * Parses MyST markdown documents into sections based on ## headings. 5 | * Each section includes all content until the next ## heading, including 6 | * any nested ### subsections. 7 | * 8 | * This simplified parser replaces the previous block-based approach with 9 | * a cleaner section-based structure that's easier to work with for translations. 10 | */ 11 | import { Section, ParsedSections, DocumentComponents } from './types'; 12 | export declare class MystParser { 13 | /** 14 | * Parse markdown content into sections based on ## headings 15 | * Each section includes all content until the next ## heading 16 | * Handles arbitrary nesting depth (##, ###, ####, #####, ######) 17 | */ 18 | parseSections(content: string, filepath: string): Promise; 19 | /** 20 | * Generate heading ID/anchor from heading text 21 | * Follows the same rules as MyST/Sphinx for consistency 22 | */ 23 | private generateHeadingId; 24 | /** 25 | * Find a section by ID (searches recursively through subsections) 26 | */ 27 | findSectionById(sections: Section[], id: string): Section | undefined; 28 | /** 29 | * Find section by position/index 30 | */ 31 | findSectionByPosition(sections: Section[], index: number): Section | undefined; 32 | /** 33 | * Validate MyST syntax by attempting to parse 34 | * Returns true if valid, false otherwise 35 | */ 36 | validateMyST(content: string, filepath: string): Promise<{ 37 | valid: boolean; 38 | error?: string; 39 | }>; 40 | /** 41 | * Parse document into explicit components: CONFIG + TITLE + INTRO + SECTIONS 42 | * 43 | * This provides a more structured view of the document that ensures 44 | * complete reconstruction by always including all components. 45 | * 46 | * @param content - The markdown content to parse 47 | * @param filepath - Path to the file (for metadata) 48 | * @returns DocumentComponents with all parts explicitly separated 49 | */ 50 | parseDocumentComponents(content: string, filepath: string): Promise; 51 | } 52 | //# sourceMappingURL=parser.d.ts.map -------------------------------------------------------------------------------- /tool-test-action-on-github/reports/README.md: -------------------------------------------------------------------------------- 1 | # Evaluation Reports 2 | 3 | This folder contains quality evaluation reports for the `action-translation` GitHub Action. 4 | 5 | Reports are generated by: 6 | 1. **`npm run evaluate`** in `../evaluate/` - Uses Claude Opus 4.5 to assess translation and diff quality 7 | 2. **Manual reviews** - Periodic human evaluation of translation accuracy 8 | 9 | ## Report Format 10 | 11 | Reports follow the naming convention: `evaluation--.md` 12 | 13 | Each report includes: 14 | - **Summary**: Pass/warn/fail counts, average scores 15 | - **Per-PR Assessments**: Individual evaluation of each PR pair 16 | - **Scope Check**: Were only the correct files/sections modified? 17 | - **Translation Quality**: Accuracy, fluency, terminology, formatting 18 | - **Diff Quality**: Position correctness, structure preservation, heading-map updates 19 | 20 | ## Reports 21 | 22 | | Report | Date | Evaluator | PRs Evaluated | Result | 23 | |--------|------|-----------|---------------|--------| 24 | | [evaluation-github-tests-gpt5-2025-11-06.md](evaluation-github-tests-gpt5-2025-11-06.md) | 2025-11-06 | GPT-5 | 21 | ✅ All PASS | 25 | 26 | ## Generating New Reports 27 | 28 | ```bash 29 | cd ../evaluate 30 | npm install 31 | npm run evaluate # Evaluate all open PR pairs 32 | npm run evaluate -- --pr 123 # Evaluate specific source PR 33 | npm run evaluate:dry-run # Preview without posting reviews 34 | ``` 35 | 36 | Reports are automatically saved to this folder with the format `evaluation-YYYY-MM-DD.md`. 37 | 38 | ## Evaluation Criteria 39 | 40 | ### Translation Quality (weighted score) 41 | - **Accuracy** (35%): Does it convey the English meaning correctly? 42 | - **Fluency** (25%): Does it read naturally in Chinese? 43 | - **Terminology** (25%): Is technical vocabulary consistent? 44 | - **Formatting** (15%): Is MyST/LaTeX/code preserved? 45 | 46 | ### Diff Quality (binary checks) 47 | - **Scope Correct**: Only intended files modified 48 | - **Position Correct**: Changes in same document locations 49 | - **Structure Preserved**: Document hierarchy maintained 50 | - **Heading-map Correct**: Frontmatter updated properly 51 | 52 | ### Verdicts 53 | - **PASS** (✅): Overall ≥8, Diff ≥8 54 | - **WARN** (⚠️): Overall ≥6, Diff ≥6 55 | - **FAIL** (❌): Below thresholds 56 | -------------------------------------------------------------------------------- /examples/sample-lecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # The Aiyagari Model 13 | 14 | ## Overview 15 | 16 | The Aiyagari model is a canonical heterogeneous agent model that extends the neoclassical growth model to include incomplete markets and borrowing constraints. 17 | 18 | Key features: 19 | 20 | - Heterogeneous agents with idiosyncratic income shocks 21 | - Incomplete markets (no insurance against income risk) 22 | - Borrowing constraints 23 | - Capital accumulation 24 | 25 | ## The Model 26 | 27 | Households face an infinite horizon problem: 28 | 29 | $$ 30 | \max E_0 \sum_{t=0}^{\infty} \beta^t u(c_t) 31 | $$ 32 | 33 | subject to: 34 | 35 | $$ 36 | c_t + a_{t+1} = w_t z_t + (1 + r_t) a_t 37 | $$ 38 | 39 | where: 40 | - $c_t$ is consumption 41 | - $a_t$ is assets 42 | - $z_t$ is the idiosyncratic productivity shock 43 | - $w_t$ is the wage rate 44 | - $r_t$ is the interest rate 45 | 46 | ## Implementation 47 | 48 | Let's implement a simple version: 49 | 50 | ```{code-cell} python 51 | import numpy as np 52 | import matplotlib.pyplot as plt 53 | 54 | def solve_household_problem(r, w, params): 55 | """ 56 | Solve the household problem given prices. 57 | 58 | Parameters 59 | ---------- 60 | r : float 61 | Interest rate 62 | w : float 63 | Wage rate 64 | params : dict 65 | Model parameters 66 | 67 | Returns 68 | ------- 69 | policy : ndarray 70 | Policy function for assets 71 | """ 72 | # Implementation here 73 | pass 74 | 75 | # Set parameters 76 | params = { 77 | 'beta': 0.96, 78 | 'gamma': 2.0, 79 | 'borrowing_limit': 0.0 80 | } 81 | 82 | print("Model parameters:", params) 83 | ``` 84 | 85 | ## Calibration 86 | 87 | We use standard parameter values from the literature: 88 | 89 | | Parameter | Value | Description | 90 | |-----------|-------|-------------| 91 | | $\beta$ | 0.96 | Discount factor | 92 | | $\gamma$ | 2.0 | Risk aversion | 93 | | $\delta$ | 0.08 | Depreciation rate | 94 | 95 | ## References 96 | 97 | Aiyagari, S. Rao (1994). "Uninsured Idiosyncratic Risk and Aggregate Saving". *Quarterly Journal of Economics*, 109(3), 659-684. 98 | -------------------------------------------------------------------------------- /tool-alignment/test-fixtures/README.md: -------------------------------------------------------------------------------- 1 | # Test Fixtures for Alignment Tool 2 | 3 | This directory contains test fixtures for the `tool-alignment` diagnostic tool. 4 | 5 | ## Structure 6 | 7 | Each test case is a numbered directory containing: 8 | - `source/` - English source files 9 | - `target/` - Chinese (zh-cn) target files 10 | - `expected.json` - Expected analysis results 11 | 12 | ## Test Cases 13 | 14 | ### Alignment Status Tests 15 | 16 | | # | Name | Description | Expected Status | 17 | |---|------|-------------|-----------------| 18 | | 01 | `aligned-perfect` | Identical structure, no heading-map | `aligned` | 19 | | 02 | `aligned-with-heading-map` | Identical structure with heading-map | `aligned` | 20 | | 03 | `likely-aligned` | Minor differences (code block count) | `likely-aligned` | 21 | | 04 | `needs-review-missing-section` | Target missing 1 of 5 sections | `needs-review` | 22 | | 05 | `needs-review-extra-section` | Target has 1 extra section | `needs-review` | 23 | | 06 | `diverged-major` | Major mismatch (6 vs 2 sections) | `diverged` | 24 | 25 | ### File Status Tests 26 | 27 | | # | Name | Description | Expected Status | 28 | |---|------|-------------|-----------------| 29 | | 07 | `missing-file` | File only exists in source | `missing` | 30 | | 08 | `extra-file` | File only exists in target | `extra` | 31 | 32 | ### Config File Tests 33 | 34 | | # | Name | Description | Expected Status | 35 | |---|------|-------------|-----------------| 36 | | 09 | `config-identical` | Identical `_toc.yml` | `identical` | 37 | | 10 | `config-diverged` | Different chapter counts | `diverged` | 38 | 39 | ### Edge Cases 40 | 41 | | # | Name | Description | Tests | 42 | |---|------|-------------|-------| 43 | | 11 | `subsections-nested` | Deep nesting (##, ###, ####, #####) | Subsection counting | 44 | | 12 | `code-math-blocks` | Code and math block counting | Block detection | 45 | | 13 | `multi-file-mixed` | Multiple files with mixed status | Full report | 46 | 47 | ### Code Integrity Tests (Phase 1b) 48 | 49 | | # | Name | Description | Tests | 50 | |---|------|-------------|-------| 51 | | 14 | `code-integrity` | Code block content comparison | Identical, normalized-match, modified, missing blocks | 52 | 53 | ## Running Tests 54 | 55 | ```bash 56 | cd tool-alignment 57 | npm test 58 | ``` 59 | 60 | ## Adding New Test Cases 61 | 62 | 1. Create numbered directory: `14-your-test-name/` 63 | 2. Add `source/` and `target/` subdirectories 64 | 3. Create test files in each 65 | 4. Add `expected.json` with expected results 66 | 5. Update this README 67 | 6. Add test case to `structural-analyzer.test.ts` 68 | -------------------------------------------------------------------------------- /tool-onboarding/reports/lecture-python-intro↔lecture-intro.zh-cn/debug/cagan_adaptive-prose.md: -------------------------------------------------------------------------------- 1 | # Claude Prose Analysis: cagan_adaptive.md 2 | 3 | Model: claude-sonnet-4-5-20250929 4 | Date: 2025-12-19T04:54:51.728Z 5 | 6 | --- 7 | 8 | ## Overall: REVIEW 9 | 10 | ## Section Analysis 11 | 12 | | Section | Source Heading | Target Heading | Status | Issue | Score | 13 | |---------|---------------|----------------|--------|-------|-------| 14 | | 1 | Overview | 引言 | ALIGNED | - | 🟢 95 | 15 | | 2 | Structure of the model | 模型结构 | ALIGNED | - | 🟢 92 | 16 | | 3 | Representing key equations with linear algebra | 关键方程的矩阵表示 | ALIGNED | - | 🟢 93 | 17 | | 4 | Harvesting insights from our matrix formulation | 求解模型 | DRIFT | TITLE | 🟡 85 | 18 | | 5 | Forecast errors and model computation | 预期与实际通货膨胀的差异 | DRIFT | TITLE, CONTENT | 🟡 75 | 19 | | 6 | [Code block - function definitions] | [Code block with modifications] | DRIFT | CONTENT | 🟡 80 | 20 | | 7 | Technical condition for stability | 稳定性的条件 | ALIGNED | - | 🟢 95 | 21 | | 8 | Experiments | Experiments | ALIGNED | - | 🟢 98 | 22 | | 9 | Experiment 1 | 实验1 | ALIGNED | - | 🟢 95 | 23 | | 10 | Experiment 2 | 实验2 | ALIGNED | - | 🟢 95 | 24 | 25 | ## Section Notes 26 | 27 | ### Section 4 28 | - **Title Issue:** "Harvesting insights" conveys extracting/deriving understanding from the formulation, while "求解模型" (Solving the model) is more literal and misses the metaphorical nuance 29 | - **Title Fix:** Consider "从矩阵表达中获得洞见" or "利用矩阵公式进行求解" to preserve the original sense of extracting insights 30 | 31 | ### Section 5 32 | - **Title Issue:** Source title "Forecast errors and model computation" addresses both conceptual (forecast errors) and practical (computation) aspects, while target "预期与实际通货膨胀的差异" (Differences between expected and actual inflation) only captures the forecast error concept 33 | - **Title Fix:** Use "预测误差与模型计算" to cover both dimensions 34 | - **Content Issue:** Target adds extensive explanatory text not present in source (e.g., "在这个适应性预期模型中,人们的通货膨胀预期通常会与实际通货膨胀率不同" and elaboration on adaptive expectations), and restructures the transition to code differently 35 | - **Content Fix:** Remove added explanatory paragraphs and maintain source's concise transition to code implementation 36 | 37 | ### Section 6 38 | - **Content Issue:** Function name changed from `solve_cagan_adaptive` to `solve`, and `create_cagan_adaptive_model` to `create_cagan_model`; parameter initialization moved and restructured with additional code block defining parameters separately; uses `np.linalg.inv()` instead of `np.linalg.solve()` for matrix operations 39 | - **Content Fix:** Maintain original function names and structure; keep parameter definitions within function call as in source; use `np.linalg.solve()` for consistency with source approach -------------------------------------------------------------------------------- /src/__tests__/fixtures/e2e/README.md: -------------------------------------------------------------------------------- 1 | # E2E Test Fixtures 2 | 3 | This directory contains end-to-end test fixtures for validating the complete translation workflow. 4 | 5 | ## Structure 6 | 7 | Each test scenario consists of 4 files: 8 | 9 | ``` 10 | XX-scenario-name-old-en.md # English document BEFORE changes 11 | XX-scenario-name-new-en.md # English document AFTER changes 12 | XX-scenario-name-current-zh.md # Chinese document (current state) 13 | XX-scenario-name-expected-zh.md # Chinese document (expected after translation) 14 | ``` 15 | 16 | ## Test Scenarios 17 | 18 | ### 01 - Intro Change Only 19 | **What it tests**: Changes to intro text only, all sections unchanged 20 | 21 | - **Change**: Intro paragraph reworded 22 | - **Expected**: Only intro translated, all sections preserved 23 | 24 | ### 02 - Title Change Only 25 | **What it tests**: Changes to document title (#) only 26 | 27 | - **Change**: Title text modified 28 | - **Expected**: Only title translated, intro and sections preserved 29 | 30 | ### 03 - Section Content Change 31 | **What it tests**: Changes to section content only 32 | 33 | - **Change**: Content within a ## section modified 34 | - **Expected**: Only that section translated, others preserved 35 | 36 | ### 04 - Section Reordering 37 | **What it tests**: Sections moved to different positions 38 | 39 | - **Change**: Section order rearranged 40 | - **Expected**: Chinese sections reordered to match, no translation needed 41 | 42 | ### 05 - Add New Section 43 | **What it tests**: New section added to document 44 | 45 | - **Change**: New ## section inserted 46 | - **Expected**: New section translated and inserted at correct position 47 | 48 | ### 06 - Delete Section 49 | **What it tests**: Section removed from document 50 | 51 | - **Change**: A ## section deleted 52 | - **Expected**: Corresponding Chinese section removed 53 | 54 | ### 07 - Subsection Change 55 | **What it tests**: Changes to ### subsection only 56 | 57 | - **Change**: Subsection content modified 58 | - **Expected**: Parent section updated with new subsection translation 59 | 60 | ### 08 - Multi-Element Change 61 | **What it tests**: Multiple changes in one commit 62 | 63 | - **Change**: Title + intro + section all modified 64 | - **Expected**: All changed elements translated, unchanged preserved 65 | 66 | ## Usage 67 | 68 | These fixtures are used by `e2e-fixtures.test.ts` which: 69 | 70 | 1. Loads the 4 files for each scenario 71 | 2. Runs the complete translation pipeline 72 | 3. Compares result against expected output 73 | 74 | ## Adding New Scenarios 75 | 76 | To add a new test scenario: 77 | 78 | 1. Create 4 files with pattern: `XX-name-{old-en,new-en,current-zh,expected-zh}.md` 79 | 2. Document the scenario in this README 80 | 3. The test suite will automatically detect and run it 81 | 82 | ## Notes 83 | 84 | - Use realistic MyST Markdown structure 85 | - Include frontmatter with jupytext config 86 | - Add heading-map in Chinese files 87 | - Keep scenarios focused on ONE type of change for clarity 88 | -------------------------------------------------------------------------------- /action.yml: -------------------------------------------------------------------------------- 1 | name: 'Translation Action' 2 | description: 'Automatically sync and review translations across repositories' 3 | author: 'QuantEcon' 4 | 5 | branding: 6 | icon: 'globe' 7 | color: 'blue' 8 | 9 | inputs: 10 | # Mode selection 11 | mode: 12 | description: 'Operation mode: sync (create translation PRs) or review (quality assessment)' 13 | required: true 14 | 15 | # Sync mode inputs 16 | target-repo: 17 | description: 'Target repository for translations (owner/repo). Required for sync mode.' 18 | required: false 19 | target-language: 20 | description: 'Target language code (e.g., zh-cn, fa). Required for sync mode.' 21 | required: false 22 | 23 | # Review mode inputs 24 | source-repo: 25 | description: 'Source repository for English content (owner/repo). Required for review mode.' 26 | required: false 27 | max-suggestions: 28 | description: 'Maximum number of improvement suggestions in review comment' 29 | required: false 30 | default: '5' 31 | 32 | # Shared inputs 33 | docs-folder: 34 | description: 'Documentation folder pattern (e.g., lectures/)' 35 | required: false 36 | default: 'lectures/' 37 | source-language: 38 | description: 'Source language code (e.g., en)' 39 | required: false 40 | default: 'en' 41 | glossary-path: 42 | description: 'Path to custom translation glossary JSON file (optional - built-in glossary used by default)' 43 | required: false 44 | default: '' 45 | toc-file: 46 | description: 'Table of contents file name' 47 | required: false 48 | default: '_toc.yml' 49 | anthropic-api-key: 50 | description: 'Anthropic API key for Claude' 51 | required: true 52 | claude-model: 53 | description: 'Claude model to use for translation' 54 | required: false 55 | default: 'claude-sonnet-4-5-20250929' 56 | github-token: 57 | description: 'GitHub token for API access' 58 | required: true 59 | pr-labels: 60 | description: 'Comma-separated labels for created PRs' 61 | required: false 62 | default: 'action-translation,automated' 63 | pr-reviewers: 64 | description: 'Comma-separated list of GitHub usernames to request as reviewers (e.g., user1,user2). Leave empty for no reviewers.' 65 | required: false 66 | default: '' 67 | pr-team-reviewers: 68 | description: 'Comma-separated list of GitHub team slugs to request as reviewers (e.g., team1,team2). Leave empty for no team reviewers.' 69 | required: false 70 | default: '' 71 | test-mode: 72 | description: 'Run in test mode (use PR head commit instead of merge commit). Set to "true" for testing.' 73 | required: false 74 | default: 'false' 75 | 76 | outputs: 77 | # Sync mode outputs 78 | pr-url: 79 | description: 'URL of the created pull request (sync mode)' 80 | files-synced: 81 | description: 'Number of files synchronized (sync mode)' 82 | 83 | # Review mode outputs 84 | review-verdict: 85 | description: 'Review verdict: PASS, WARN, or FAIL (review mode)' 86 | translation-score: 87 | description: 'Overall translation quality score 1-10 (review mode)' 88 | diff-score: 89 | description: 'Diff quality score 1-10 (review mode)' 90 | 91 | runs: 92 | using: 'node20' 93 | main: 'dist/index.js' 94 | -------------------------------------------------------------------------------- /tool-test-action-on-github/evaluate/src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Types for Translation Quality Evaluation 3 | */ 4 | 5 | export interface PRPair { 6 | sourceNumber: number; 7 | targetNumber: number; 8 | sourceTitle: string; 9 | targetTitle: string; 10 | sourceBranch: string; 11 | targetBranch: string; 12 | sourceUrl: string; 13 | targetUrl: string; 14 | testScenario: string; 15 | } 16 | 17 | export interface FileDiff { 18 | filename: string; 19 | status: 'added' | 'modified' | 'removed' | 'renamed'; 20 | additions: number; 21 | deletions: number; 22 | patch?: string; 23 | previousFilename?: string; 24 | } 25 | 26 | export interface TranslationContext { 27 | sourceEnglish: string; 28 | targetChinese: string; 29 | } 30 | 31 | export interface ChangedSection { 32 | heading: string; // The section heading (e.g., "## Introduction") 33 | changeType: 'added' | 'modified' | 'deleted'; 34 | englishContent?: string; // For added/modified sections 35 | chineseContent?: string; // For added/modified sections 36 | } 37 | 38 | export interface TranslationQualityResult { 39 | score: number; // 1-10 40 | accuracy: number; // 1-10: Does it accurately convey the English meaning? 41 | fluency: number; // 1-10: Does it read naturally in Chinese? 42 | terminology: number; // 1-10: Is technical terminology consistent? 43 | formatting: number; // 1-10: Is MyST/math/code preserved? 44 | syntaxErrors: string[]; // Markdown/MyST syntax errors found 45 | issues: string[]; 46 | strengths: string[]; 47 | summary: string; 48 | } 49 | 50 | export interface DiffQualityResult { 51 | score: number; // 1-10 52 | scopeCorrect: boolean; // Only intended files changed? 53 | positionCorrect: boolean; // Changes in correct document locations? 54 | structurePreserved: boolean; // Document structure maintained? 55 | headingMapCorrect: boolean; // Heading-map properly updated? 56 | issues: string[]; 57 | summary: string; 58 | scopeDetails: string; 59 | positionDetails: string; 60 | structureDetails: string; 61 | } 62 | 63 | export interface EvaluationResult { 64 | prPair: PRPair; 65 | timestamp: string; 66 | translationQuality: TranslationQualityResult; 67 | diffQuality: DiffQualityResult; 68 | overallScore: number; 69 | overallVerdict: 'PASS' | 'WARN' | 'FAIL'; 70 | reviewComment: string; 71 | } 72 | 73 | export interface EvaluationReport { 74 | generatedAt: string; 75 | evaluator: string; 76 | sourceRepo: string; 77 | targetRepo: string; 78 | prPairsEvaluated: number; 79 | results: EvaluationResult[]; 80 | summary: { 81 | passed: number; 82 | warned: number; 83 | failed: number; 84 | averageTranslationScore: number; 85 | averageDiffScore: number; 86 | commonIssues: string[]; 87 | }; 88 | } 89 | 90 | export interface EvaluationOptions { 91 | anthropicApiKey: string; 92 | githubToken: string; 93 | prNumbers?: number[]; // PR numbers to evaluate (from either repo), or all open if undefined 94 | postReviews: boolean; // Post review comments to translation PRs 95 | outputFile?: string; // Path for report output 96 | maxSuggestions: number; // Maximum number of suggestions per evaluation (default: 5) 97 | model?: string; // Claude model to use for evaluation (default: opus-4-5) 98 | } 99 | -------------------------------------------------------------------------------- /docs/presentations/README.md: -------------------------------------------------------------------------------- 1 | # Presentations 2 | 3 | Modern presentation for the Translation Sync Action project built with Marp and Mermaid. 4 | 5 | ## Quick Start 6 | 7 | Build the presentation: 8 | 9 | ```bash 10 | ./build.sh 11 | ``` 12 | 13 | This generates: 14 | - `action-translation-sync.pdf` - PDF presentation 15 | - `action-translation-sync.html` - HTML presentation 16 | - `diagrams/workflow.png` - Pre-rendered Mermaid diagram 17 | 18 | ## Files 19 | 20 | - `action-translation-sync.md` - Marp Markdown source (default theme) 21 | - `diagrams/workflow.mmd` - Mermaid diagram source 22 | - `diagrams/workflow.png` - Generated diagram (created by build script) 23 | - `build.sh` - Automated build script 24 | 25 | ## Prerequisites 26 | 27 | Install the required tools: 28 | 29 | ```bash 30 | # Install Marp CLI 31 | npm install -g @marp-team/marp-cli 32 | 33 | # Install Mermaid CLI (for diagram generation) 34 | npm install -g @mermaid-js/mermaid-cli 35 | ``` 36 | 37 | ## Building 38 | 39 | ### Full Build 40 | 41 | ```bash 42 | ./build.sh 43 | ``` 44 | 45 | This script: 46 | 1. Generates Mermaid diagrams as PNG (using `mmdc`) 47 | 2. Builds PDF presentation (using `marp`) 48 | 3. Builds HTML presentation (using `marp`) 49 | 50 | ### Manual Build 51 | 52 | Generate diagram: 53 | ```bash 54 | mmdc -i diagrams/workflow.mmd -o diagrams/workflow.png -t neutral -b transparent 55 | ``` 56 | 57 | Build PDF: 58 | ```bash 59 | marp action-translation-sync.md -o action-translation-sync.pdf --allow-local-files 60 | ``` 61 | 62 | Build HTML: 63 | ```bash 64 | marp action-translation-sync.md -o action-translation-sync.html --allow-local-files 65 | ``` 66 | 67 | ## Presentation Contents 68 | 69 | 6 slides covering: 70 | 71 | 1. **Title** - Project introduction 72 | 2. **What It Does** - Key capabilities and workflow 73 | 3. **How It Works** - Section-based translation approach 74 | 4. **Translation Workflow** - Visual Mermaid diagram (pre-rendered) 75 | 5. **LLM Integration** - Claude Sonnet 4.5 translation modes (UPDATE and NEW) 76 | 6. **Status & Resources** - Current state and getting started 77 | 78 | ## Editing 79 | 80 | ### Markdown Source 81 | 82 | Edit `action-translation-sync.md` - standard Markdown with Marp directives. 83 | 84 | The presentation uses Marp's **default theme** with custom CSS for two-column layouts. 85 | 86 | ### Diagrams 87 | 88 | Edit `diagrams/workflow.mmd` - standard Mermaid syntax (horizontal LR layout, 1100px width). 89 | 90 | Run build script to regenerate PNG after changes. 91 | 92 | ### Theme 93 | 94 | Using Marp's built-in **default** theme - clean and simple, works well for content-heavy presentations. 95 | 96 | ## Presenting 97 | 98 | **PDF:** Open `action-translation-sync.pdf` in any PDF viewer 99 | **HTML:** Open `action-translation-sync.html` in a browser (arrow keys to navigate) 100 | 101 | ## Changelog 102 | 103 | ### 2025-10-23 104 | - Created Marp presentation with default theme 105 | - Pre-render Mermaid diagrams with CLI for reliable rendering 106 | - Added automated build script 107 | - 6 slides covering project overview and technical details 108 | - Horizontal workflow diagram (LR layout, 1100px width) 109 | - Two-column layouts using CSS Grid 110 | - Both UPDATE and NEW modes show glossary usage 111 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Example Workflow Configuration 2 | 3 | This directory contains example workflow files for using the Translation Sync action. 4 | 5 | ## Basic Usage 6 | 7 | Create `.github/workflows/sync-translations.yml` in your source repository: 8 | 9 | ```yaml 10 | name: Sync Translations to Chinese 11 | 12 | on: 13 | pull_request: 14 | types: [closed] 15 | paths: 16 | - 'lectures/**/*.md' 17 | 18 | jobs: 19 | sync-to-chinese: 20 | if: github.event.pull_request.merged == true 21 | runs-on: ubuntu-latest 22 | 23 | steps: 24 | - name: Sync translations 25 | uses: quantecon/action-translation@v0.7 26 | with: 27 | mode: sync 28 | target-repo: 'quantecon/lecture-python.zh-cn' 29 | target-language: 'zh-cn' 30 | docs-folder: 'lectures/' 31 | source-language: 'en' 32 | glossary-path: '.github/translation-glossary.json' 33 | toc-file: '_toc.yml' 34 | anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} 35 | github-token: ${{ secrets.GITHUB_TOKEN }} 36 | pr-labels: 'translation-sync,automated' 37 | pr-reviewers: 'translation-team' 38 | ``` 39 | 40 | ## Multi-Language Support 41 | 42 | You can sync to multiple target repositories: 43 | 44 | ```yaml 45 | name: Sync Translations 46 | 47 | on: 48 | pull_request: 49 | types: [closed] 50 | paths: 51 | - 'lectures/**/*.md' 52 | 53 | jobs: 54 | sync-to-chinese: 55 | if: github.event.pull_request.merged == true 56 | runs-on: ubuntu-latest 57 | steps: 58 | - uses: quantecon/action-translation@v0.7 59 | with: 60 | mode: sync 61 | target-repo: 'quantecon/lecture-python.zh-cn' 62 | target-language: 'zh-cn' 63 | docs-folder: 'lectures/' 64 | glossary-path: '.github/translation-glossary-zh-cn.json' 65 | anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} 66 | github-token: ${{ secrets.GITHUB_TOKEN }} 67 | 68 | sync-to-japanese: 69 | if: github.event.pull_request.merged == true 70 | runs-on: ubuntu-latest 71 | steps: 72 | - uses: quantecon/action-translation@v0.7 73 | with: 74 | mode: sync 75 | target-repo: 'quantecon/lecture-python.ja' 76 | target-language: 'ja' 77 | docs-folder: 'lectures/' 78 | glossary-path: '.github/translation-glossary-ja.json' 79 | anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} 80 | github-token: ${{ secrets.GITHUB_TOKEN }} 81 | ``` 82 | 83 | ## Required Secrets 84 | 85 | Add these secrets to your repository settings: 86 | 87 | - `ANTHROPIC_API_KEY`: Your Anthropic API key for Claude 88 | - `GITHUB_TOKEN`: Automatically provided by GitHub Actions 89 | 90 | ## Glossary File 91 | 92 | Create `.github/translation-glossary.json`: 93 | 94 | ```json 95 | { 96 | "version": "1.0", 97 | "terms": [ 98 | { 99 | "en": "equilibrium", 100 | "zh-cn": "均衡", 101 | "ja": "均衡", 102 | "context": "economics" 103 | }, 104 | { 105 | "en": "steady state", 106 | "zh-cn": "稳态", 107 | "ja": "定常状態" 108 | } 109 | ], 110 | "style_guide": { 111 | "preserve_code_blocks": true, 112 | "preserve_math": true, 113 | "preserve_citations": true, 114 | "preserve_myst_directives": true 115 | } 116 | } 117 | ``` 118 | -------------------------------------------------------------------------------- /docs/presentations/action-translation-sync.md: -------------------------------------------------------------------------------- 1 | --- 2 | marp: true 3 | paginate: true 4 | --- 5 | 6 | 13 | 14 | 15 | 16 | # Translation Action 17 | 18 | **AI-Powered Translation Automation for Lectures** 19 | 20 | GitHub Action • Claude Sonnet 4.5 • MyST Markdown 21 | 22 | _QuantEcon Project_ 23 | 24 | --- 25 | 26 | # What It Does 27 | 28 | **Automatically translates and reviews lectures when source content changes** 29 | 30 | Monitor merged PRs → Detect changes → Translate → Create PR → AI Review 31 | 32 | ## Key Capabilities 33 | 34 | ✓ **Smart Diff Translation** – Only translates modified sections 35 | ✓ **MyST Markdown Aware** – Preserves code, math, directives 36 | ✓ **Consistent Terminology** – Built-in glossaries (357 terms) 37 | ✓ **AI-Powered Review** – Automated quality assessment with scoring 38 | ✓ **Language Extensible** – Configurable rules per target language 39 | 40 | --- 41 | 42 | # How It Works 43 | 44 | ## Section-Based Translation Approach 45 | 46 |
47 |
48 | 49 | ### ❌ Problem: Block-Level 50 | 51 | - Can't match across languages 52 | - Loses translation context 53 | - Complex mapping logic 54 | 55 |
56 |
57 | 58 | ### ✅ Solution: Section-Based 59 | 60 | - Match by position 61 | - Translate full sections 62 | - Simple: Add, Update, Delete 63 | 64 |
65 |
66 | 67 | --- 68 | 69 | # Translation Workflow 70 | 71 | ![width:1100px](diagrams/workflow.png) 72 | 73 | --- 74 | 75 | # LLM-Powered Translation (Claude Sonnet 4.5) 76 | 77 |
78 |
79 | 80 | ### UPDATE Mode 81 | _(changed sections)_ 82 | 83 | - Sends: old EN + new EN + current translation 84 | - Claude understands what changed 85 | - Preserves style and terminology 86 | - Uses glossary for consistency 87 | 88 |
89 |
90 | 91 | ### NEW Mode 92 | _(new sections)_ 93 | 94 | - Translates with full context 95 | - Uses glossary for consistency 96 | - Maintains document structure 97 | 98 |
99 |
100 | 101 | --- 102 | 103 | # Two Operational Modes 104 | 105 |
106 |
107 | 108 | ### 🔄 Sync Mode 109 | _(runs in SOURCE repo)_ 110 | 111 | - Monitors merged PRs 112 | - Detects changed sections 113 | - Translates incrementally 114 | - Creates PR in target repo 115 | - Updates heading-maps 116 | 117 |
118 |
119 | 120 | ### 📝 Review Mode 121 | _(runs in TARGET repo)_ 122 | 123 | - Evaluates translation PRs 124 | - Scores: accuracy, fluency, terminology 125 | - Checks diff correctness 126 | - Posts review comments 127 | - PASS / WARN / FAIL verdicts 128 | 129 |
130 |
131 | 132 | --- 133 | 134 | # Status & Getting Started 135 | 136 |
137 |
138 | 139 | ## Current Status 140 | 141 | 📦 **v0.7.0** – Testing & Development 142 | 🔄 **Two Modes**: Sync + Review 143 | ✅ 183 tests passing 144 | 🧪 24 GitHub test scenarios 145 | 146 | ## Use Cases 147 | 148 | - Multi-language documentation 149 | - Educational content 150 | - OSS localization 151 | 152 |
153 |
154 | 155 | ## Resources 156 | 157 | **GitHub**: QuantEcon/action-translation 158 | 159 | **Docs**: 11 guides in `docs/` 160 | 161 | **Tools**: Bulk translator, test framework 162 | 163 | **License**: MIT 164 | 165 |
166 |
167 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/19-multi-file-lecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Linear Algebra Foundations 13 | 14 | This lecture introduces fundamental concepts in linear algebra that are essential for quantitative economics and data science. We'll explore vector spaces, matrices, eigenvalues, and their applications to economic problems. 15 | 16 | ## Vector Spaces 17 | 18 | A vector space is a collection of objects called vectors, which can be added together and multiplied by scalars. Understanding vector spaces is crucial for modern economic analysis and machine learning applications. 19 | 20 | Mathematically, a vector $\mathbf{v} \in \mathbb{R}^n$ can be represented as: 21 | 22 | $$ 23 | \mathbf{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix} 24 | $$ 25 | 26 | Let's create and visualize some vectors in Python: 27 | 28 | ```{code-cell} python 29 | import numpy as np 30 | import matplotlib.pyplot as plt 31 | 32 | # Create two vectors 33 | v1 = np.array([2, 3]) 34 | v2 = np.array([1, 4]) 35 | 36 | # Visualize vectors 37 | fig, ax = plt.subplots(figsize=(8, 6)) 38 | ax.quiver(0, 0, v1[0], v1[1], angles='xy', scale_units='xy', scale=1, color='blue', label='v1') 39 | ax.quiver(0, 0, v2[0], v2[1], angles='xy', scale_units='xy', scale=1, color='red', label='v2') 40 | ax.set_xlim(-1, 5) 41 | ax.set_ylim(-1, 5) 42 | ax.set_xlabel('x-axis') 43 | ax.set_ylabel('y-axis') 44 | ax.set_title('Vector Representation in 2D Space') 45 | ax.legend() 46 | ax.grid(True) 47 | plt.show() 48 | ``` 49 | 50 | ### Basic Properties 51 | 52 | Vector spaces satisfy several key properties: 53 | - Closure under addition and scalar multiplication 54 | - Existence of additive identity (zero vector) 55 | - Existence of additive inverses 56 | - Associativity and commutativity of addition 57 | 58 | These properties ensure that vector spaces behave predictably under mathematical operations, forming the foundation for linear transformations. 59 | 60 | #### Applications in Economics 61 | 62 | Vector space properties are fundamental in economic modeling. The closure property ensures that combinations of feasible allocations remain feasible, while the existence of inverses allows us to model debts and obligations. 63 | 64 | The sum of two vectors $\mathbf{u}$ and $\mathbf{v}$ is defined component-wise: 65 | 66 | ```{math} 67 | \mathbf{u} + \mathbf{v} = \begin{bmatrix} u_1 + v_1 \\ u_2 + v_2 \\ \vdots \\ u_n + v_n \end{bmatrix} 68 | ``` 69 | 70 | ## Matrix Operations 71 | 72 | Matrices are rectangular arrays of numbers that represent linear transformations. They are fundamental tools in economic modeling, data analysis, and optimization problems. 73 | 74 | A general $m \times n$ matrix has the form: 75 | 76 | $$ 77 | A = \begin{bmatrix} 78 | a_{11} & a_{12} & \cdots & a_{1n} \\ 79 | a_{21} & a_{22} & \cdots & a_{2n} \\ 80 | \vdots & \vdots & \ddots & \vdots \\ 81 | a_{m1} & a_{m2} & \cdots & a_{mn} 82 | \end{bmatrix} 83 | $$ 84 | 85 | ### Eigenvalues and Eigenvectors 86 | 87 | Eigenvalues and eigenvectors reveal important structural properties of linear transformations. For a square matrix $A$, an eigenvector $\mathbf{v}$ and corresponding eigenvalue $\lambda$ satisfy: 88 | 89 | $$ 90 | A\mathbf{v} = \lambda \mathbf{v} 91 | $$ 92 | 93 | These concepts are crucial for understanding dynamic systems, stability analysis, and dimensionality reduction techniques like PCA. 94 | -------------------------------------------------------------------------------- /dist/file-processor.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Section-Based File Processor 3 | * 4 | * Orchestrates the translation process for a single file using section-based approach. 5 | * 6 | * Key operations: 7 | * 1. Detect section-level changes between old and new English documents 8 | * 2. Match sections to target document (by position) 9 | * 3. Translate changed sections (update mode for modified, new mode for added) 10 | * 4. Reconstruct target document with translated sections 11 | * 12 | * This is much simpler than the old block-based approach! 13 | */ 14 | import { TranslationService } from './translator'; 15 | import { Glossary } from './types'; 16 | export declare class FileProcessor { 17 | private parser; 18 | private diffDetector; 19 | private translator; 20 | private debug; 21 | constructor(translationService: TranslationService, debug?: boolean); 22 | private log; 23 | /** 24 | * Process a file using component-based approach 25 | * Always reconstructs complete document: CONFIG + TITLE + INTRO + SECTIONS 26 | * This ensures no components get lost during translation updates 27 | */ 28 | processSectionBased(oldContent: string, newContent: string, targetContent: string, filepath: string, sourceLanguage: string, targetLanguage: string, glossary?: Glossary): Promise; 29 | /** 30 | * Helper: Translate a new section 31 | */ 32 | private translateNewSection; 33 | /** 34 | * Reconstruct document from components: CONFIG + TITLE + INTRO + SECTIONS 35 | * This ensures we always produce a complete, valid document 36 | */ 37 | private reconstructFromComponents; 38 | /** 39 | * Process a full document (for new files) 40 | */ 41 | processFull(content: string, filepath: string, sourceLanguage: string, targetLanguage: string, glossary?: Glossary): Promise; 42 | /** 43 | * Parse translated content to extract subsections and strip them from parent content 44 | * This ensures subsections are properly populated in the heading-map and not duplicated 45 | * Returns both the subsections and the content without subsections 46 | */ 47 | private parseTranslatedSubsections; 48 | /** 49 | * Find target section using heading map (preferred) or ID fallback 50 | * Returns the actual section object or undefined if not found 51 | */ 52 | private findTargetSectionByHeadingMap; 53 | /** 54 | * Helper to find the index of a section in the NEW source sections 55 | * Used for position-based fallback 56 | */ 57 | private findSourceSectionIndex; 58 | /** 59 | * Find target section index using heading map (preferred) or position fallback 60 | * 61 | * Strategy: 62 | * 1. Look up translated heading in heading map 63 | * 2. Search for that heading in target sections 64 | * 3. If not found, fall back to position-based matching 65 | * 66 | * @deprecated Use findTargetSectionByHeadingMap instead - this version has position tracking bugs 67 | */ 68 | private findTargetSectionIndex; 69 | /** 70 | * Find matching section index in target document 71 | * Match by section ID (heading ID like "economic-models", "introduction", etc.) 72 | * 73 | * @deprecated Use findTargetSectionIndex with heading map instead 74 | */ 75 | private findMatchingSectionIndex; 76 | /** 77 | * Serialize a section with all its subsections into markdown text 78 | * This ensures subsections are included when translating 79 | */ 80 | private serializeSection; 81 | /** 82 | * Validate the translated content has valid MyST syntax 83 | */ 84 | validateMyST(content: string, filepath: string): Promise<{ 85 | valid: boolean; 86 | error?: string; 87 | }>; 88 | } 89 | //# sourceMappingURL=file-processor.d.ts.map -------------------------------------------------------------------------------- /src/language-config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Language-specific configuration for translation prompts 3 | * 4 | * Each target language can have specific instructions that are appended to the translation prompts. 5 | * This allows for language-specific typography, punctuation, and stylistic rules. 6 | */ 7 | 8 | export interface LanguageConfig { 9 | /** Language code (e.g., 'zh-cn', 'ja', 'es') */ 10 | code: string; 11 | /** Language name in English */ 12 | name: string; 13 | /** Additional rules to append to translation prompts */ 14 | additionalRules: string[]; 15 | } 16 | 17 | /** 18 | * Language-specific configurations 19 | * 20 | * To add a new language: 21 | * 1. Add a new entry with the language code as the key 22 | * 2. Include any language-specific typography or punctuation rules 23 | * 3. The language will automatically be available for use 24 | */ 25 | export const LANGUAGE_CONFIGS: Record = { 26 | 'zh-cn': { 27 | code: 'zh-cn', 28 | name: 'Chinese (Simplified)', 29 | additionalRules: [ 30 | 'Use proper full-width Chinese punctuation marks (,:。!?) not ASCII punctuation (,.!?) in prose text', 31 | ], 32 | }, 33 | 'fa': { 34 | code: 'fa', 35 | name: 'Persian (Farsi)', 36 | additionalRules: [ 37 | 'Use proper Persian punctuation marks (، ؛ ؟) without any RTL directionality markup', 38 | 'Keep technical terms and code examples in English/Latin script', 39 | 'Use formal/academic Persian style appropriate for educational content', 40 | ], 41 | }, 42 | // Future language configurations can be added here: 43 | // 'ja': { 44 | // code: 'ja', 45 | // name: 'Japanese', 46 | // additionalRules: [ 47 | // 'Use proper Japanese punctuation marks (、。「」)', 48 | // ], 49 | // }, 50 | // 'es': { 51 | // code: 'es', 52 | // name: 'Spanish', 53 | // additionalRules: [ 54 | // 'Use inverted punctuation marks (¿?) for questions and (¡!) for exclamations', 55 | // ], 56 | // }, 57 | }; 58 | 59 | /** 60 | * Get language-specific configuration 61 | * Returns empty rules array if language not configured 62 | */ 63 | export function getLanguageConfig(languageCode: string): LanguageConfig { 64 | const normalized = languageCode.toLowerCase(); 65 | return LANGUAGE_CONFIGS[normalized] || { 66 | code: languageCode, 67 | name: languageCode, 68 | additionalRules: [], 69 | }; 70 | } 71 | 72 | /** 73 | * Format additional rules for inclusion in prompts 74 | * Returns empty string if no additional rules 75 | */ 76 | export function formatAdditionalRules(languageCode: string): string { 77 | const config = getLanguageConfig(languageCode); 78 | if (config.additionalRules.length === 0) { 79 | return ''; 80 | } 81 | return config.additionalRules.map(rule => rule).join('\n'); 82 | } 83 | 84 | /** 85 | * Get list of supported language codes 86 | */ 87 | export function getSupportedLanguages(): string[] { 88 | return Object.keys(LANGUAGE_CONFIGS); 89 | } 90 | 91 | /** 92 | * Check if a language code is supported (has configuration) 93 | */ 94 | export function isLanguageSupported(languageCode: string): boolean { 95 | const normalized = languageCode.toLowerCase(); 96 | return normalized in LANGUAGE_CONFIGS; 97 | } 98 | 99 | /** 100 | * Validate language code and throw descriptive error if not supported 101 | */ 102 | export function validateLanguageCode(languageCode: string): void { 103 | if (!isLanguageSupported(languageCode)) { 104 | const supported = getSupportedLanguages().join(', '); 105 | throw new Error( 106 | `Unsupported target language: '${languageCode}'. ` + 107 | `Supported languages: ${supported}. ` + 108 | `To add a new language, update LANGUAGE_CONFIGS in src/language-config.ts` 109 | ); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /dist/language-config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | /** 3 | * Language-specific configuration for translation prompts 4 | * 5 | * Each target language can have specific instructions that are appended to the translation prompts. 6 | * This allows for language-specific typography, punctuation, and stylistic rules. 7 | */ 8 | Object.defineProperty(exports, "__esModule", { value: true }); 9 | exports.LANGUAGE_CONFIGS = void 0; 10 | exports.getLanguageConfig = getLanguageConfig; 11 | exports.formatAdditionalRules = formatAdditionalRules; 12 | exports.getSupportedLanguages = getSupportedLanguages; 13 | exports.isLanguageSupported = isLanguageSupported; 14 | exports.validateLanguageCode = validateLanguageCode; 15 | /** 16 | * Language-specific configurations 17 | * 18 | * To add a new language: 19 | * 1. Add a new entry with the language code as the key 20 | * 2. Include any language-specific typography or punctuation rules 21 | * 3. The language will automatically be available for use 22 | */ 23 | exports.LANGUAGE_CONFIGS = { 24 | 'zh-cn': { 25 | code: 'zh-cn', 26 | name: 'Chinese (Simplified)', 27 | additionalRules: [ 28 | 'Use proper full-width Chinese punctuation marks (,:。!?) not ASCII punctuation (,.!?) in prose text', 29 | ], 30 | }, 31 | 'fa': { 32 | code: 'fa', 33 | name: 'Persian (Farsi)', 34 | additionalRules: [ 35 | 'Use proper Persian punctuation marks (، ؛ ؟) without any RTL directionality markup', 36 | 'Keep technical terms and code examples in English/Latin script', 37 | 'Use formal/academic Persian style appropriate for educational content', 38 | ], 39 | }, 40 | // Future language configurations can be added here: 41 | // 'ja': { 42 | // code: 'ja', 43 | // name: 'Japanese', 44 | // additionalRules: [ 45 | // 'Use proper Japanese punctuation marks (、。「」)', 46 | // ], 47 | // }, 48 | // 'es': { 49 | // code: 'es', 50 | // name: 'Spanish', 51 | // additionalRules: [ 52 | // 'Use inverted punctuation marks (¿?) for questions and (¡!) for exclamations', 53 | // ], 54 | // }, 55 | }; 56 | /** 57 | * Get language-specific configuration 58 | * Returns empty rules array if language not configured 59 | */ 60 | function getLanguageConfig(languageCode) { 61 | const normalized = languageCode.toLowerCase(); 62 | return exports.LANGUAGE_CONFIGS[normalized] || { 63 | code: languageCode, 64 | name: languageCode, 65 | additionalRules: [], 66 | }; 67 | } 68 | /** 69 | * Format additional rules for inclusion in prompts 70 | * Returns empty string if no additional rules 71 | */ 72 | function formatAdditionalRules(languageCode) { 73 | const config = getLanguageConfig(languageCode); 74 | if (config.additionalRules.length === 0) { 75 | return ''; 76 | } 77 | return config.additionalRules.map(rule => rule).join('\n'); 78 | } 79 | /** 80 | * Get list of supported language codes 81 | */ 82 | function getSupportedLanguages() { 83 | return Object.keys(exports.LANGUAGE_CONFIGS); 84 | } 85 | /** 86 | * Check if a language code is supported (has configuration) 87 | */ 88 | function isLanguageSupported(languageCode) { 89 | const normalized = languageCode.toLowerCase(); 90 | return normalized in exports.LANGUAGE_CONFIGS; 91 | } 92 | /** 93 | * Validate language code and throw descriptive error if not supported 94 | */ 95 | function validateLanguageCode(languageCode) { 96 | if (!isLanguageSupported(languageCode)) { 97 | const supported = getSupportedLanguages().join(', '); 98 | throw new Error(`Unsupported target language: '${languageCode}'. ` + 99 | `Supported languages: ${supported}. ` + 100 | `To add a new language, update LANGUAGE_CONFIGS in src/language-config.ts`); 101 | } 102 | } 103 | //# sourceMappingURL=language-config.js.map -------------------------------------------------------------------------------- /src/__tests__/parser-components.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Tests for parseDocumentComponents method 3 | */ 4 | 5 | import { MystParser } from '../parser'; 6 | 7 | describe('MystParser.parseDocumentComponents', () => { 8 | let parser: MystParser; 9 | 10 | beforeEach(() => { 11 | parser = new MystParser(); 12 | }); 13 | 14 | it('should parse a complete document with all components', async () => { 15 | const content = `--- 16 | jupytext: 17 | text_representation: 18 | extension: .md 19 | format_name: myst 20 | --- 21 | 22 | # Introduction to Economics 23 | 24 | This is the intro paragraph explaining what this document is about. 25 | 26 | ## Basic Concepts 27 | 28 | Economics is the study of scarce resources. 29 | 30 | ### Key Terms 31 | 32 | - Scarcity 33 | - Opportunity cost 34 | 35 | ## Mathematical Framework 36 | 37 | The production function is important.`; 38 | 39 | const result = await parser.parseDocumentComponents(content, 'test.md'); 40 | 41 | // Check CONFIG 42 | expect(result.config).toContain('jupytext:'); 43 | expect(result.config).toContain('format_name: myst'); 44 | 45 | // Check TITLE 46 | expect(result.title).toBe('# Introduction to Economics'); 47 | expect(result.titleText).toBe('Introduction to Economics'); 48 | 49 | // Check INTRO 50 | expect(result.intro).toContain('This is the intro paragraph'); 51 | 52 | // Check SECTIONS 53 | expect(result.sections).toHaveLength(2); 54 | expect(result.sections[0].heading).toBe('## Basic Concepts'); 55 | expect(result.sections[0].subsections).toHaveLength(1); 56 | expect(result.sections[1].heading).toBe('## Mathematical Framework'); 57 | 58 | // Check metadata 59 | expect(result.metadata.sectionCount).toBe(2); 60 | }); 61 | 62 | it('should handle empty intro', async () => { 63 | const content = `--- 64 | config: test 65 | --- 66 | 67 | # Title 68 | 69 | ## First Section 70 | 71 | Content here.`; 72 | 73 | const result = await parser.parseDocumentComponents(content, 'test.md'); 74 | 75 | expect(result.title).toBe('# Title'); 76 | expect(result.intro).toBe(''); 77 | expect(result.sections).toHaveLength(1); 78 | }); 79 | 80 | it('should handle no sections (only title and intro)', async () => { 81 | const content = `--- 82 | config: test 83 | --- 84 | 85 | # Title 86 | 87 | This is just some intro text with no sections. 88 | 89 | More intro text.`; 90 | 91 | const result = await parser.parseDocumentComponents(content, 'test.md'); 92 | 93 | expect(result.title).toBe('# Title'); 94 | expect(result.intro).toContain('This is just some intro text'); 95 | expect(result.sections).toHaveLength(0); 96 | }); 97 | 98 | it('should handle empty frontmatter', async () => { 99 | const content = `# Title 100 | 101 | Intro text here. 102 | 103 | ## Section One 104 | 105 | Content.`; 106 | 107 | const result = await parser.parseDocumentComponents(content, 'test.md'); 108 | 109 | expect(result.config).toBe(''); 110 | expect(result.title).toBe('# Title'); 111 | expect(result.intro).toContain('Intro text here'); 112 | expect(result.sections).toHaveLength(1); 113 | }); 114 | 115 | it('should throw error if no title heading found', async () => { 116 | const content = `--- 117 | config: test 118 | --- 119 | 120 | ## Section Without Title 121 | 122 | This is invalid.`; 123 | 124 | await expect( 125 | parser.parseDocumentComponents(content, 'test.md') 126 | ).rejects.toThrow('Expected # title heading'); 127 | }); 128 | 129 | it('should handle title with special characters', async () => { 130 | const content = `# Introduction to Economics: Theory & Practice 131 | 132 | Intro text. 133 | 134 | ## Section`; 135 | 136 | const result = await parser.parseDocumentComponents(content, 'test.md'); 137 | 138 | expect(result.title).toBe('# Introduction to Economics: Theory & Practice'); 139 | expect(result.titleText).toBe('Introduction to Economics: Theory & Practice'); 140 | }); 141 | }); 142 | -------------------------------------------------------------------------------- /dist/types.d.ts.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /src/__tests__/language-config.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Tests for language-specific configuration 3 | */ 4 | 5 | import { 6 | getLanguageConfig, 7 | formatAdditionalRules, 8 | getSupportedLanguages, 9 | isLanguageSupported, 10 | validateLanguageCode 11 | } from '../language-config'; 12 | 13 | describe('Language Configuration', () => { 14 | describe('getLanguageConfig', () => { 15 | it('should return Chinese config for zh-cn', () => { 16 | const config = getLanguageConfig('zh-cn'); 17 | expect(config.code).toBe('zh-cn'); 18 | expect(config.name).toBe('Chinese (Simplified)'); 19 | expect(config.additionalRules).toHaveLength(1); 20 | expect(config.additionalRules[0]).toContain('full-width Chinese punctuation'); 21 | }); 22 | 23 | it('should handle case insensitive language codes', () => { 24 | const config1 = getLanguageConfig('zh-cn'); 25 | const config2 = getLanguageConfig('ZH-CN'); 26 | const config3 = getLanguageConfig('Zh-Cn'); 27 | 28 | expect(config1).toEqual(config2); 29 | expect(config2).toEqual(config3); 30 | }); 31 | 32 | it('should return empty rules for unconfigured languages', () => { 33 | const config = getLanguageConfig('ja'); 34 | expect(config.code).toBe('ja'); 35 | expect(config.additionalRules).toHaveLength(0); 36 | }); 37 | 38 | it('should return empty rules for unknown languages', () => { 39 | const config = getLanguageConfig('unknown-lang'); 40 | expect(config.code).toBe('unknown-lang'); 41 | expect(config.additionalRules).toHaveLength(0); 42 | }); 43 | }); 44 | 45 | describe('formatAdditionalRules', () => { 46 | it('should format Chinese rules as string', () => { 47 | const rules = formatAdditionalRules('zh-cn'); 48 | expect(rules).toContain('full-width Chinese punctuation'); 49 | }); 50 | 51 | it('should return empty string for unconfigured languages', () => { 52 | const rules = formatAdditionalRules('ja'); 53 | expect(rules).toBe(''); 54 | }); 55 | 56 | it('should return empty string for unknown languages', () => { 57 | const rules = formatAdditionalRules('unknown-lang'); 58 | expect(rules).toBe(''); 59 | }); 60 | }); 61 | 62 | describe('getSupportedLanguages', () => { 63 | it('should return array of supported language codes', () => { 64 | const languages = getSupportedLanguages(); 65 | expect(Array.isArray(languages)).toBe(true); 66 | expect(languages).toContain('zh-cn'); 67 | }); 68 | 69 | it('should not be empty', () => { 70 | const languages = getSupportedLanguages(); 71 | expect(languages.length).toBeGreaterThan(0); 72 | }); 73 | }); 74 | 75 | describe('isLanguageSupported', () => { 76 | it('should return true for configured languages', () => { 77 | expect(isLanguageSupported('zh-cn')).toBe(true); 78 | expect(isLanguageSupported('ZH-CN')).toBe(true); 79 | }); 80 | 81 | it('should return false for unconfigured languages', () => { 82 | expect(isLanguageSupported('ja')).toBe(false); 83 | expect(isLanguageSupported('es')).toBe(false); 84 | expect(isLanguageSupported('unknown')).toBe(false); 85 | }); 86 | }); 87 | 88 | describe('validateLanguageCode', () => { 89 | it('should not throw for supported languages', () => { 90 | expect(() => validateLanguageCode('zh-cn')).not.toThrow(); 91 | expect(() => validateLanguageCode('ZH-CN')).not.toThrow(); 92 | }); 93 | 94 | it('should throw for unsupported languages', () => { 95 | expect(() => validateLanguageCode('ja')).toThrow(/Unsupported target language/); 96 | expect(() => validateLanguageCode('unknown')).toThrow(/Unsupported target language/); 97 | }); 98 | 99 | it('should include supported languages in error message', () => { 100 | expect(() => validateLanguageCode('ja')).toThrow(/zh-cn/); 101 | }); 102 | 103 | it('should suggest updating LANGUAGE_CONFIGS in error', () => { 104 | expect(() => validateLanguageCode('es')).toThrow(/LANGUAGE_CONFIGS/); 105 | }); 106 | }); 107 | }); 108 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/23-special-chars-lecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Programming for Economics 13 | 14 | This lecture covers programming concepts and tools essential for modern economic analysis. 15 | 16 | ## Using `numpy` Arrays 17 | 18 | The `numpy` library provides efficient array operations for numerical computing. Arrays are the foundation of scientific computing in Python. 19 | 20 | NumPy arrays support vectorized operations, avoiding slow Python loops: 21 | 22 | ```python 23 | import numpy as np 24 | arr = np.array([1, 2, 3, 4, 5]) 25 | result = arr ** 2 # Vectorized squaring 26 | ``` 27 | 28 | ### Creating Arrays with `np.arange()` and `np.linspace()` 29 | 30 | Different array creation methods serve different purposes. The `np.arange()` function creates arrays with specified step sizes: 31 | 32 | ```python 33 | x = np.arange(0, 10, 0.5) # From 0 to 10, step 0.5 34 | ``` 35 | 36 | Meanwhile, `np.linspace()` creates arrays with a specified number of points: 37 | 38 | ```python 39 | y = np.linspace(0, 1, 100) # 100 points from 0 to 1 40 | ``` 41 | 42 | ## Working with **Pandas DataFrames** 43 | 44 | The **pandas** library provides powerful data manipulation capabilities. DataFrames are two-dimensional labeled data structures. 45 | 46 | ### Reading Data: `pd.read_csv()` vs `pd.read_excel()` 47 | 48 | Different file formats require different reading functions: 49 | 50 | - **CSV files**: Use `pd.read_csv('data.csv')` 51 | - **Excel files**: Use `pd.read_excel('data.xlsx')` 52 | - **JSON files**: Use `pd.read_json('data.json')` 53 | 54 | ## *Matplotlib* Visualization Basics 55 | 56 | *Matplotlib* is the foundational plotting library for Python. It provides fine-grained control over plot appearance. 57 | 58 | ### The `plt.plot()` Function 59 | 60 | Basic line plots are created with `plt.plot(x, y)`: 61 | 62 | ```python 63 | import matplotlib.pyplot as plt 64 | plt.plot([1, 2, 3], [4, 5, 6]) 65 | plt.xlabel('x-axis') 66 | plt.ylabel('y-axis') 67 | plt.title('Simple Plot') 68 | plt.show() 69 | ``` 70 | 71 | ## Using [QuantEcon](https://quantecon.org) Libraries 72 | 73 | The [QuantEcon](https://quantecon.org) project provides specialized tools for economic modeling. Visit the [documentation](https://quanteconpy.readthedocs.io/) for details. 74 | 75 | ### Installing `quantecon` Package 76 | 77 | Install via pip: 78 | 79 | ```bash 80 | pip install quantecon 81 | ``` 82 | 83 | Or with conda: 84 | 85 | ```bash 86 | conda install -c conda-forge quantecon 87 | ``` 88 | 89 | ## Special Cases: $\LaTeX$ in Headings 90 | 91 | Mathematical notation appears inline: $f(x) = x^2 + 2x + 1$. 92 | 93 | ### The $\beta$-Coefficient in Regression 94 | 95 | The regression coefficient $\beta$ measures the relationship between variables: 96 | 97 | $$ 98 | y = \alpha + \beta x + \epsilon 99 | $$ 100 | 101 | ### Computing $\mathbb{E}[X]$ (Expected Values) 102 | 103 | Expected values $\mathbb{E}[X]$ represent average outcomes: 104 | 105 | $$ 106 | \mathbb{E}[X] = \sum_{i} x_i P(X = x_i) 107 | $$ 108 | 109 | ## Questions & Answers 110 | 111 | Common questions about Python for economics: 112 | 113 | - **Q**: Which is faster: `numpy` or plain Python? 114 | - **A**: `numpy` is typically 10-100x faster for numerical operations 115 | 116 | - **Q**: Can I use `pandas` with large datasets? 117 | - **A**: Yes, but consider `dask` for datasets larger than RAM 118 | 119 | ## "Edge Cases" and [Special] {Characters} 120 | 121 | This section tests various special characters in headings. 122 | 123 | ### Using `matplotlib`'s `plt.subplot()` for Multiple Plots 124 | 125 | The subplot function creates multiple plots in one figure: 126 | 127 | ```python 128 | fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) 129 | ax1.plot(x, y1) 130 | ax2.plot(x, y2) 131 | ``` 132 | 133 | ## Summary 134 | 135 | Programming tools like **numpy**, *pandas*, and `matplotlib` are essential for modern economic research. Master these libraries to efficiently analyze data and visualize results. 136 | -------------------------------------------------------------------------------- /docs/TEST-REPOSITORIES.md: -------------------------------------------------------------------------------- 1 | # GitHub Repository Testing 2 | 3 | **Purpose**: Real-world end-to-end validation using actual GitHub repositories and workflows. 4 | 5 | --- 6 | 7 | ## Overview 8 | 9 | Beyond unit tests (`npm test`), we validate the action in a real GitHub environment with actual PRs, cross-repo operations, and GitHub Actions workflows. 10 | 11 | **Test Repositories**: 12 | - **Source**: `QuantEcon/test-translation-sync` (English) 13 | - **Target**: `QuantEcon/test-translation-sync.zh-cn` (Chinese translations) 14 | 15 | --- 16 | 17 | ## Quick Start 18 | 19 | ### Automated Testing 20 | 21 | ```bash 22 | # From repository root 23 | ./tool-test-action-on-github/test-action-on-github.sh 24 | ``` 25 | 26 | This script automatically: 27 | 1. Resets test repositories to clean state 28 | 2. Closes all old PRs 29 | 3. Creates 24 test PRs covering different scenarios 30 | 4. Triggers GitHub Actions on each PR 31 | 5. Validates translations in target repo 32 | 33 | **Test Scenarios**: New files, section updates, deletions, subsections, root-level files, and more. 34 | 35 | --- 36 | 37 | ## First-Time Setup 38 | 39 | Only needed once: 40 | 41 | ```bash 42 | # 1. Create test repositories 43 | gh repo create QuantEcon/test-translation-sync --public 44 | gh repo create QuantEcon/test-translation-sync.zh-cn --public 45 | 46 | # 2. Add Claude API key 47 | gh secret set ANTHROPIC_API_KEY --repo QuantEcon/test-translation-sync 48 | ``` 49 | 50 | Then run the test script above. 51 | 52 | --- 53 | 54 | ## Why GitHub Testing? 55 | 56 | | Benefit | Description | 57 | |---------|-------------| 58 | | **Real Environment** | Tests actual GitHub Actions workflow | 59 | | **Cross-Repo** | Validates PR creation in target repo | 60 | | **Full Integration** | Tests API permissions, secrets, webhooks | 61 | | **Safe** | Dedicated test repos don't affect production | 62 | | **Repeatable** | Automated reset for consistent testing | 63 | 64 | --- 65 | 66 | ## Monitoring 67 | 68 | ```bash 69 | # View test PRs in source repo 70 | gh pr list --repo QuantEcon/test-translation-sync --label test-translation 71 | 72 | # View translation PRs in target repo 73 | gh pr list --repo QuantEcon/test-translation-sync.zh-cn 74 | 75 | # Check GitHub Actions logs 76 | gh run list --repo QuantEcon/test-translation-sync 77 | gh run view --log 78 | ``` 79 | 80 | --- 81 | 82 | ## Iterative Testing 83 | 84 | The script is idempotent - safe to run repeatedly: 85 | 86 | ```bash 87 | # Make code changes 88 | vim src/translator.ts 89 | npm run build && npm run package 90 | 91 | # Test again (auto-resets everything) 92 | ./tool-test-action-on-github/test-action-on-github.sh 93 | 94 | # Check results 95 | gh run list --repo QuantEcon/test-translation-sync 96 | ``` 97 | 98 | --- 99 | 100 | ## Detailed Documentation 101 | 102 | For complete information on: 103 | - Test scenarios and data 104 | - Troubleshooting 105 | - Script internals 106 | - File structure and workflow 107 | 108 | **See: [tool-test-action-on-github/README.md](../tool-test-action-on-github/README.md)** 109 | 110 | --- 111 | 112 | ## Local vs GitHub Testing 113 | 114 | | Aspect | Local (`npm test`) | GitHub Testing | 115 | |--------|-------------------|----------------| 116 | | **Speed** | ~2 seconds | ~2-3 minutes per scenario | 117 | | **Scope** | Unit/integration | End-to-end workflow | 118 | | **Cost** | Free | ~$0.50 per full test run | 119 | | **Use** | Every commit, TDD | Pre-release validation | 120 | 121 | **Both are essential**: Local tests for development speed, GitHub tests for release confidence. 122 | 123 | --- 124 | 125 | ## Cleanup 126 | 127 | The script auto-cleans between runs. When completely done: 128 | 129 | ```bash 130 | # Archive (read-only) 131 | gh repo archive QuantEcon/test-translation-sync 132 | gh repo archive QuantEcon/test-translation-sync.zh-cn 133 | 134 | # Or delete 135 | gh repo delete QuantEcon/test-translation-sync --yes 136 | gh repo delete QuantEcon/test-translation-sync.zh-cn --yes 137 | ``` 138 | 139 | --- 140 | 141 | **Ready?** Run `./tool-test-action-on-github/test-action-on-github.sh` to start testing! 🚀 142 | 143 | For detailed documentation, see [tool-test-action-on-github/README.md](../tool-test-action-on-github/README.md). 144 | -------------------------------------------------------------------------------- /dist/diff-detector.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"diff-detector.js","sourceRoot":"","sources":["../src/diff-detector.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /tool-alignment/src/triage.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Triage Module for Phase 3: File-Centric Diagnostics 3 | * 4 | * Scans all files in a repository and produces a prioritized 5 | * list of files needing attention. 6 | */ 7 | 8 | import * as path from 'path'; 9 | import { 10 | FileAnalyzer, 11 | extractRepoName, 12 | sortByPriority, 13 | Thresholds, 14 | DEFAULT_THRESHOLDS 15 | } from './file-analyzer'; 16 | import { 17 | TriageResult, 18 | FileDiagnostic, 19 | FileAction, 20 | TriageOptions 21 | } from './types'; 22 | 23 | const VERSION = '0.2.0'; 24 | 25 | export interface TriageProgress { 26 | current: number; 27 | total: number; 28 | file: string; 29 | } 30 | 31 | export type ProgressCallback = (progress: TriageProgress) => void; 32 | 33 | export class Triage { 34 | private analyzer: FileAnalyzer; 35 | 36 | constructor(thresholds: Thresholds = DEFAULT_THRESHOLDS) { 37 | this.analyzer = new FileAnalyzer(thresholds); 38 | } 39 | 40 | /** 41 | * Triage all files in a repository 42 | */ 43 | async triageRepository( 44 | options: TriageOptions, 45 | onProgress?: ProgressCallback 46 | ): Promise { 47 | const { source, target, docsFolder } = options; 48 | 49 | // Discover files 50 | const sourceFiles = this.analyzer.getMarkdownFiles(source, docsFolder); 51 | const targetFiles = this.analyzer.getMarkdownFiles(target, docsFolder); 52 | 53 | // Combine unique files 54 | const allFiles = [...new Set([...sourceFiles, ...targetFiles])].sort(); 55 | 56 | // Analyze each file 57 | const files: FileDiagnostic[] = []; 58 | 59 | for (let i = 0; i < allFiles.length; i++) { 60 | const file = allFiles[i]; 61 | 62 | if (onProgress) { 63 | onProgress({ current: i + 1, total: allFiles.length, file }); 64 | } 65 | 66 | const diagnostic = await this.analyzer.analyzeFile( 67 | source, 68 | target, 69 | docsFolder, 70 | file 71 | ); 72 | files.push(diagnostic); 73 | } 74 | 75 | // Sort by priority 76 | const sortedFiles = sortByPriority(files); 77 | 78 | // Filter files needing attention 79 | const filesNeedingAttention = sortedFiles.filter( 80 | f => f.action !== 'ok' || f.priority !== 'ok' 81 | ); 82 | 83 | // Count by action 84 | const byAction = this.countByAction(files); 85 | 86 | // Build result 87 | const result: TriageResult = { 88 | metadata: { 89 | sourceRepo: extractRepoName(source), 90 | sourcePath: path.resolve(source), 91 | targetPath: path.resolve(target), 92 | docsFolder, 93 | generatedAt: new Date().toISOString(), 94 | version: VERSION, 95 | }, 96 | summary: { 97 | totalFiles: files.length, 98 | ok: byAction['ok'] || 0, 99 | needsAttention: files.length - (byAction['ok'] || 0), 100 | byAction, 101 | }, 102 | files: sortedFiles, 103 | filesNeedingAttention, 104 | }; 105 | 106 | return result; 107 | } 108 | 109 | /** 110 | * Analyze a single file 111 | */ 112 | async analyzeFile( 113 | source: string, 114 | target: string, 115 | docsFolder: string, 116 | filename: string 117 | ): Promise { 118 | return this.analyzer.analyzeFile(source, target, docsFolder, filename); 119 | } 120 | 121 | /** 122 | * Count files by action type 123 | */ 124 | private countByAction(files: FileDiagnostic[]): Record { 125 | const counts: Record = { 126 | 'ok': 0, 127 | 'resync': 0, 128 | 'review-code': 0, 129 | 'review-quality': 0, 130 | 'retranslate': 0, 131 | 'create': 0, 132 | 'diverged': 0, 133 | }; 134 | 135 | for (const file of files) { 136 | counts[file.action]++; 137 | } 138 | 139 | return counts; 140 | } 141 | } 142 | 143 | /** 144 | * Convenience function for quick triage 145 | */ 146 | export async function triageRepository( 147 | options: TriageOptions, 148 | thresholds?: Thresholds, 149 | onProgress?: ProgressCallback 150 | ): Promise { 151 | const triage = new Triage(thresholds); 152 | return triage.triageRepository(options, onProgress); 153 | } 154 | -------------------------------------------------------------------------------- /tool-onboarding/src/discovery.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * File discovery and pairing between source and target repositories 3 | */ 4 | 5 | import * as fs from 'fs'; 6 | import * as path from 'path'; 7 | import { execSync } from 'child_process'; 8 | 9 | // ============================================================================= 10 | // FILE DISCOVERY 11 | // ============================================================================= 12 | 13 | /** 14 | * Get all markdown files in a docs folder 15 | */ 16 | export function getMarkdownFiles(repoRoot: string, docsFolder: string): string[] { 17 | const fullPath = path.join(repoRoot, docsFolder); 18 | if (!fs.existsSync(fullPath)) { 19 | return []; 20 | } 21 | 22 | return fs.readdirSync(fullPath) 23 | .filter(f => f.endsWith('.md')) 24 | .sort(); 25 | } 26 | 27 | /** 28 | * Discover and pair files between source and target repositories 29 | */ 30 | export function discoverFiles( 31 | source: string, 32 | target: string, 33 | docsFolder: string 34 | ): { 35 | sourceFiles: string[]; 36 | targetFiles: string[]; 37 | paired: string[]; 38 | sourceOnly: string[]; 39 | targetOnly: string[]; 40 | } { 41 | const sourceFiles = getMarkdownFiles(source, docsFolder); 42 | const targetFiles = getMarkdownFiles(target, docsFolder); 43 | 44 | const sourceSet = new Set(sourceFiles); 45 | const targetSet = new Set(targetFiles); 46 | 47 | const paired = sourceFiles.filter(f => targetSet.has(f)); 48 | const sourceOnly = sourceFiles.filter(f => !targetSet.has(f)); 49 | const targetOnly = targetFiles.filter(f => !sourceSet.has(f)); 50 | 51 | return { sourceFiles, targetFiles, paired, sourceOnly, targetOnly }; 52 | } 53 | 54 | // ============================================================================= 55 | // GIT METADATA 56 | // ============================================================================= 57 | 58 | /** 59 | * Get the last modified date of a file from git history 60 | */ 61 | export function getGitLastModified( 62 | repoRoot: string, 63 | docsFolder: string, 64 | file: string 65 | ): string | undefined { 66 | try { 67 | const filePath = docsFolder ? path.join(docsFolder, file) : file; 68 | const result = execSync( 69 | `git log -1 --format="%ai" -- "${filePath}"`, 70 | { cwd: repoRoot, encoding: 'utf8' } 71 | ).trim(); 72 | 73 | if (result) { 74 | // Parse "2024-07-19 10:30:00 -0400" format 75 | return result.split(' ')[0]; // Return just the date part 76 | } 77 | } catch { 78 | // Git command failed, return undefined 79 | } 80 | return undefined; 81 | } 82 | 83 | /** 84 | * Determine update direction based on dates 85 | * @returns '→' if source is newer, '←' if target is newer, '=' if same/unknown 86 | */ 87 | export function getUpdateDirection( 88 | sourceDate?: string, 89 | targetDate?: string 90 | ): '→' | '←' | '=' { 91 | if (!sourceDate || !targetDate) return '='; 92 | 93 | const srcTime = new Date(sourceDate).getTime(); 94 | const tgtTime = new Date(targetDate).getTime(); 95 | 96 | if (srcTime > tgtTime) return '→'; // Source newer 97 | if (tgtTime > srcTime) return '←'; // Target newer 98 | return '='; 99 | } 100 | 101 | /** 102 | * Get human-readable direction description 103 | */ 104 | export function getDirectionDescription(direction: '→' | '←' | '='): string { 105 | switch (direction) { 106 | case '→': return 'Source newer'; 107 | case '←': return 'Target newer'; 108 | case '=': return 'Same date'; 109 | } 110 | } 111 | 112 | // ============================================================================= 113 | // FILE CONTENT 114 | // ============================================================================= 115 | 116 | /** 117 | * Read file content safely 118 | */ 119 | export function readFileContent(filePath: string): string | null { 120 | try { 121 | return fs.readFileSync(filePath, 'utf8'); 122 | } catch { 123 | return null; 124 | } 125 | } 126 | 127 | /** 128 | * Check if file exists 129 | */ 130 | export function fileExists(filePath: string): boolean { 131 | return fs.existsSync(filePath); 132 | } 133 | 134 | /** 135 | * Get full path to a file in a repository's docs folder 136 | */ 137 | export function getFilePath(repoRoot: string, docsFolder: string, file: string): string { 138 | return path.join(repoRoot, docsFolder, file); 139 | } 140 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/14-delete-subsection-lecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Linear Algebra Foundations 13 | 14 | This lecture introduces fundamental concepts in linear algebra that are essential for quantitative economics. We'll explore vector spaces, matrices, and their applications to economic problems. 15 | 16 | ## Vector Spaces 17 | 18 | A vector space is a collection of objects called vectors, which can be added together and multiplied by scalars. Understanding vector spaces is crucial for modern economic analysis. 19 | 20 | Mathematically, a vector $\mathbf{v} \in \mathbb{R}^n$ can be represented as: 21 | 22 | $$ 23 | \mathbf{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix} 24 | $$ 25 | 26 | Let's create and visualize some vectors in Python: 27 | 28 | ```{code-cell} python 29 | import numpy as np 30 | import matplotlib.pyplot as plt 31 | 32 | # Create two vectors 33 | v1 = np.array([2, 3]) 34 | v2 = np.array([1, 4]) 35 | 36 | # Visualize vectors 37 | fig, ax = plt.subplots(figsize=(8, 6)) 38 | ax.quiver(0, 0, v1[0], v1[1], angles='xy', scale_units='xy', scale=1, color='blue', label='v1') 39 | ax.quiver(0, 0, v2[0], v2[1], angles='xy', scale_units='xy', scale=1, color='red', label='v2') 40 | ax.set_xlim(-1, 5) 41 | ax.set_ylim(-1, 5) 42 | ax.set_xlabel('x-axis') 43 | ax.set_ylabel('y-axis') 44 | ax.set_title('Vector Representation in 2D Space') 45 | ax.legend() 46 | ax.grid(True) 47 | plt.show() 48 | ``` 49 | 50 | ### Basic Properties 51 | 52 | Vector spaces satisfy several key properties: 53 | - Closure under addition and scalar multiplication 54 | - Existence of additive identity (zero vector) 55 | - Existence of additive inverses 56 | 57 | These properties ensure that vector spaces behave predictably under mathematical operations. 58 | 59 | #### Applications in Economics 60 | 61 | Vector space properties are fundamental in economic modeling. The closure property ensures that combinations of feasible allocations remain feasible, while the existence of inverses allows us to model debts and obligations. 62 | 63 | The sum of two vectors $\mathbf{u}$ and $\mathbf{v}$ is defined component-wise: 64 | 65 | ```{math} 66 | \mathbf{u} + \mathbf{v} = \begin{bmatrix} u_1 + v_1 \\ u_2 + v_2 \\ \vdots \\ u_n + v_n \end{bmatrix} 67 | ``` 68 | 69 | ## Eigenvalues and Eigenvectors 70 | 71 | Eigenvalues and eigenvectors reveal important properties of linear transformations. An eigenvector $v$ of matrix $A$ satisfies: 72 | 73 | ```{math} 74 | :label: eigenvalue-equation 75 | Av = \lambda v 76 | ``` 77 | 78 | where $\lambda$ is the eigenvalue. This fundamental equation appears throughout economics, from growth theory to stability analysis. 79 | 80 | For an $n \times n$ matrix $A$, the characteristic polynomial is: 81 | 82 | $$ 83 | \det(A - \lambda I) = 0 84 | $$ 85 | 86 | Solving this equation yields the eigenvalues. Let's compute eigenvalues for a transition matrix: 87 | 88 | ```{code-cell} python 89 | # Create a transition matrix for a simple Markov chain 90 | # States: Employed, Unemployed 91 | transition_matrix = np.array([ 92 | [0.95, 0.05], # Employed -> (Employed, Unemployed) 93 | [0.20, 0.80] # Unemployed -> (Employed, Unemployed) 94 | ]) 95 | 96 | # Calculate eigenvalues and eigenvectors 97 | eigenvalues, eigenvectors = np.linalg.eig(transition_matrix) 98 | 99 | print("Transition Matrix:") 100 | print(transition_matrix) 101 | print("\nEigenvalues:") 102 | print(np.round(eigenvalues, 4)) 103 | print("\nEigenvectors:") 104 | print(np.round(eigenvectors, 4)) 105 | 106 | # The eigenvector corresponding to eigenvalue 1 gives steady-state distribution 107 | steady_state_index = np.argmax(eigenvalues) 108 | steady_state = eigenvectors[:, steady_state_index] 109 | steady_state = steady_state / steady_state.sum() # Normalize 110 | 111 | print("\nSteady-State Distribution:") 112 | print(f"Employed: {steady_state[0]:.2%}") 113 | print(f"Unemployed: {steady_state[1]:.2%}") 114 | ``` 115 | 116 | These concepts are essential for analyzing dynamic economic systems, such as growth models and stability analysis. 117 | 118 | The power iteration method can be used to find the dominant eigenvalue: 119 | 120 | $$ 121 | \lambda_1 = \lim_{k \to \infty} \frac{\|A^k \mathbf{v}_0\|}{\|A^{k-1} \mathbf{v}_0\|} 122 | $$ 123 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/base-lecture-zh-cn.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | heading-map: 11 | Linear Algebra Foundations: 线性代数基础 12 | Vector Spaces: 向量空间 13 | Vector Spaces::Basic Properties: 基本性质 14 | Vector Spaces::Basic Properties::Applications in Economics: 在经济学中的应用 15 | Matrix Operations: 矩阵运算 16 | Matrix Operations::Applications in Economics: 经济学应用 17 | Eigenvalues and Eigenvectors: 特征值与特征向量 18 | --- 19 | 20 | # 线性代数基础 21 | 22 | 本讲座介绍了对定量经济学至关重要的线性代数基本概念。我们将探讨向量空间、矩阵及其在经济问题中的应用。 23 | 24 | ## 向量空间 25 | 26 | 向量空间是称为向量的对象的集合,这些对象可以相加并与标量相乘。理解向量空间对现代经济分析至关重要。 27 | 28 | 数学上,向量 $\mathbf{v} \in \mathbb{R}^n$ 可以表示为: 29 | 30 | $$ 31 | \mathbf{v} = \begin{bmatrix} v_1 \\ v_2 \\ \vdots \\ v_n \end{bmatrix} 32 | $$ 33 | 34 | 让我们用 Python 创建并可视化一些向量: 35 | 36 | ```{code-cell} python 37 | import numpy as np 38 | import matplotlib.pyplot as plt 39 | 40 | # 创建两个向量 41 | v1 = np.array([2, 3]) 42 | v2 = np.array([1, 4]) 43 | 44 | # 可视化向量 45 | fig, ax = plt.subplots(figsize=(8, 6)) 46 | ax.quiver(0, 0, v1[0], v1[1], angles='xy', scale_units='xy', scale=1, color='blue', label='v1') 47 | ax.quiver(0, 0, v2[0], v2[1], angles='xy', scale_units='xy', scale=1, color='red', label='v2') 48 | ax.set_xlim(-1, 5) 49 | ax.set_ylim(-1, 5) 50 | ax.set_xlabel('x轴') 51 | ax.set_ylabel('y轴') 52 | ax.set_title('二维空间中的向量表示') 53 | ax.legend() 54 | ax.grid(True) 55 | plt.show() 56 | ``` 57 | 58 | ### 基本性质 59 | 60 | 向量空间满足几个关键性质: 61 | - 加法和标量乘法下的封闭性 62 | - 加法单位元(零向量)的存在 63 | - 加法逆元的存在 64 | 65 | 这些性质确保向量空间在数学运算下表现可预测。 66 | 67 | #### 在经济学中的应用 68 | 69 | 向量空间性质在经济建模中是基础性的。封闭性质确保可行配置的组合仍然可行,而逆元的存在使我们能够建模债务和义务。 70 | 71 | 两个向量 $\mathbf{u}$ 和 $\mathbf{v}$ 的和按分量定义: 72 | 73 | ```{math} 74 | \mathbf{u} + \mathbf{v} = \begin{bmatrix} u_1 + v_1 \\ u_2 + v_2 \\ \vdots \\ u_n + v_n \end{bmatrix} 75 | ``` 76 | 77 | ## 矩阵运算 78 | 79 | 矩阵是表示线性变换的数字矩形数组。它们是经济建模和数据分析的基本工具。 80 | 81 | 一般的 $m \times n$ 矩阵具有以下形式: 82 | 83 | $$ 84 | A = \begin{bmatrix} 85 | a_{11} & a_{12} & \cdots & a_{1n} \\ 86 | a_{21} & a_{22} & \cdots & a_{2n} \\ 87 | \vdots & \vdots & \ddots & \vdots \\ 88 | a_{m1} & a_{m2} & \cdots & a_{mn} 89 | \end{bmatrix} 90 | $$ 91 | 92 | 矩阵乘法允许我们组合线性变换。对于矩阵 $A$ 和 $B$,乘积 $AB$ 表示先应用变换 $B$,然后应用变换 $A$。 93 | 94 | 让我们用一个经济应用来演示矩阵运算: 95 | 96 | ```{code-cell} python 97 | # 创建一个三部门经济的简单投入产出矩阵 98 | # 部门:农业、制造业、服务业 99 | input_output = np.array([ 100 | [0.2, 0.3, 0.1], # 农业投入 101 | [0.3, 0.2, 0.2], # 制造业投入 102 | [0.1, 0.2, 0.3] # 服务业投入 103 | ]) 104 | 105 | # 最终需求向量(十亿单位) 106 | final_demand = np.array([100, 150, 200]) 107 | 108 | # 使用里昂惕夫逆矩阵计算总产出:x = (I - A)^{-1} * d 109 | I = np.eye(3) 110 | leontief_inverse = np.linalg.inv(I - input_output) 111 | total_output = leontief_inverse @ final_demand 112 | 113 | print("投入产出矩阵:") 114 | print(input_output) 115 | print("\n里昂惕夫逆矩阵:") 116 | print(np.round(leontief_inverse, 3)) 117 | print("\n所需总产出(十亿):") 118 | print(np.round(total_output, 2)) 119 | ``` 120 | 121 | ### 经济学应用 122 | 123 | 经济模型经常使用矩阵来表示: 124 | - 生产中的投入产出关系 125 | - 马尔可夫链中的转移概率 126 | - 线性方程组中的系数矩阵 127 | 128 | 里昂惕夫逆矩阵 $(I - A)^{-1}$ 特别重要,其中 $I$ 是单位矩阵,$A$ 是投入产出系数矩阵。 129 | 130 | ## 特征值与特征向量 131 | 132 | 特征值和特征向量揭示了线性变换的重要性质。矩阵 $A$ 的特征向量 $v$ 满足: 133 | 134 | ```{math} 135 | :label: eigenvalue-equation 136 | Av = \lambda v 137 | ``` 138 | 139 | 其中 $\lambda$ 是特征值。这个基本方程贯穿整个经济学,从增长理论到稳定性分析。 140 | 141 | 对于 $n \times n$ 矩阵 $A$,特征多项式为: 142 | 143 | $$ 144 | \det(A - \lambda I) = 0 145 | $$ 146 | 147 | 求解此方程得到特征值。让我们为转移矩阵计算特征值: 148 | 149 | ```{code-cell} python 150 | # 为简单马尔可夫链创建转移矩阵 151 | # 状态:就业、失业 152 | transition_matrix = np.array([ 153 | [0.95, 0.05], # 就业 -> (就业, 失业) 154 | [0.20, 0.80] # 失业 -> (就业, 失业) 155 | ]) 156 | 157 | # 计算特征值和特征向量 158 | eigenvalues, eigenvectors = np.linalg.eig(transition_matrix) 159 | 160 | print("转移矩阵:") 161 | print(transition_matrix) 162 | print("\n特征值:") 163 | print(np.round(eigenvalues, 4)) 164 | print("\n特征向量:") 165 | print(np.round(eigenvectors, 4)) 166 | 167 | # 对应于特征值1的特征向量给出稳态分布 168 | steady_state_index = np.argmax(eigenvalues) 169 | steady_state = eigenvectors[:, steady_state_index] 170 | steady_state = steady_state / steady_state.sum() # 归一化 171 | 172 | print("\n稳态分布:") 173 | print(f"就业:{steady_state[0]:.2%}") 174 | print(f"失业:{steady_state[1]:.2%}") 175 | ``` 176 | 177 | 这些概念对于分析动态经济系统(如增长模型和稳定性分析)至关重要。 178 | 179 | 幂迭代法可用于找到主特征值: 180 | 181 | $$ 182 | \lambda_1 = \lim_{k \to \infty} \frac{\|A^k \mathbf{v}_0\|}{\|A^{k-1} \mathbf{v}_0\|} 183 | $$ 184 | -------------------------------------------------------------------------------- /tool-onboarding/src/__tests__/discovery.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Tests for discovery.ts - File discovery and git metadata 3 | */ 4 | 5 | import * as path from 'path'; 6 | import { 7 | getMarkdownFiles, 8 | discoverFiles, 9 | getUpdateDirection, 10 | getDirectionDescription, 11 | getFilePath 12 | } from '../discovery'; 13 | 14 | describe('getMarkdownFiles', () => { 15 | // Note: These tests use the actual test-fixtures directory 16 | const fixturesPath = path.join(__dirname, '../../test-fixtures'); 17 | 18 | it('should find markdown files in a directory', () => { 19 | const alignedFixture = path.join(fixturesPath, '01-aligned-perfect'); 20 | 21 | // This test only runs if fixtures exist 22 | try { 23 | const files = getMarkdownFiles(path.join(alignedFixture, 'source'), ''); 24 | expect(Array.isArray(files)).toBe(true); 25 | // If there are files, they should be .md 26 | files.forEach(file => { 27 | expect(file.endsWith('.md')).toBe(true); 28 | }); 29 | } catch { 30 | // Skip if fixtures don't exist 31 | console.log('Skipping: test fixtures not found'); 32 | } 33 | }); 34 | 35 | it('should return empty array for non-existent directory', () => { 36 | const files = getMarkdownFiles('/non/existent/path', ''); 37 | expect(files).toEqual([]); 38 | }); 39 | }); 40 | 41 | describe('discoverFiles', () => { 42 | it('should pair source and target files correctly', () => { 43 | const fixturesPath = path.join(__dirname, '../../test-fixtures/01-aligned-perfect'); 44 | 45 | try { 46 | const discovered = discoverFiles( 47 | path.join(fixturesPath, 'source'), 48 | path.join(fixturesPath, 'target'), 49 | '' 50 | ); 51 | 52 | expect(discovered).toHaveProperty('paired'); 53 | expect(discovered).toHaveProperty('sourceOnly'); 54 | expect(discovered).toHaveProperty('targetOnly'); 55 | expect(Array.isArray(discovered.paired)).toBe(true); 56 | } catch { 57 | console.log('Skipping: test fixtures not found'); 58 | } 59 | }); 60 | 61 | it('should identify source-only files', () => { 62 | const fixturesPath = path.join(__dirname, '../../test-fixtures/07-missing-file'); 63 | 64 | try { 65 | const discovered = discoverFiles( 66 | path.join(fixturesPath, 'source'), 67 | path.join(fixturesPath, 'target'), 68 | '' 69 | ); 70 | 71 | // Missing file fixture should have source-only files 72 | expect(discovered.sourceOnly.length).toBeGreaterThanOrEqual(0); 73 | } catch { 74 | console.log('Skipping: test fixtures not found'); 75 | } 76 | }); 77 | }); 78 | 79 | describe('getUpdateDirection', () => { 80 | it('should return → when source is newer', () => { 81 | const direction = getUpdateDirection('2024-12-15', '2024-12-01'); 82 | expect(direction).toBe('→'); 83 | }); 84 | 85 | it('should return ← when target is newer', () => { 86 | const direction = getUpdateDirection('2024-12-01', '2024-12-15'); 87 | expect(direction).toBe('←'); 88 | }); 89 | 90 | it('should return = when dates are equal', () => { 91 | const direction = getUpdateDirection('2024-12-15', '2024-12-15'); 92 | expect(direction).toBe('='); 93 | }); 94 | 95 | it('should return = when dates are missing', () => { 96 | expect(getUpdateDirection(undefined, undefined)).toBe('='); 97 | expect(getUpdateDirection('2024-12-15', undefined)).toBe('='); 98 | expect(getUpdateDirection(undefined, '2024-12-15')).toBe('='); 99 | }); 100 | }); 101 | 102 | describe('getDirectionDescription', () => { 103 | it('should describe → direction', () => { 104 | const desc = getDirectionDescription('→'); 105 | expect(desc).toContain('Source'); 106 | expect(desc.toLowerCase()).toContain('newer'); 107 | }); 108 | 109 | it('should describe ← direction', () => { 110 | const desc = getDirectionDescription('←'); 111 | expect(desc).toContain('Target'); 112 | expect(desc.toLowerCase()).toContain('newer'); 113 | }); 114 | 115 | it('should describe = state', () => { 116 | const desc = getDirectionDescription('='); 117 | expect(desc.toLowerCase()).toContain('same'); 118 | }); 119 | }); 120 | 121 | describe('getFilePath', () => { 122 | it('should join base, docs folder and file paths', () => { 123 | const result = getFilePath('/base/path', 'docs', 'file.md'); 124 | expect(result).toBe('/base/path/docs/file.md'); 125 | }); 126 | 127 | it('should handle empty docs folder', () => { 128 | const result = getFilePath('/base', '', 'file.md'); 129 | expect(result).toBe('/base/file.md'); 130 | }); 131 | 132 | it('should handle nested docs folder', () => { 133 | const result = getFilePath('/base', 'lectures/intro', 'file.md'); 134 | expect(result).toBe('/base/lectures/intro/file.md'); 135 | }); 136 | }); 137 | -------------------------------------------------------------------------------- /docs/CLAUDE-MODELS.md: -------------------------------------------------------------------------------- 1 | # Using Different Claude Models 2 | 3 | The `claude-model` parameter allows you to specify which Claude model to use for translations. 4 | 5 | ## Default Model 6 | 7 | By default, the action uses **`claude-sonnet-4-5-20250929`** (Claude Sonnet 4.5). 8 | 9 | No configuration needed - it just works! 10 | 11 | ```yaml 12 | - uses: quantecon/action-translation@v0.7 13 | with: 14 | mode: sync 15 | target-repo: 'quantecon/lecture-python.zh-cn' 16 | target-language: 'zh-cn' 17 | anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} 18 | github-token: ${{ secrets.GITHUB_TOKEN }} 19 | # claude-model: 'claude-sonnet-4-5-20250929' # This is the default 20 | ``` 21 | 22 | ## Using a Different Model 23 | 24 | You can specify a different Claude model using the `claude-model` parameter: 25 | 26 | ```yaml 27 | - uses: quantecon/action-translation@v0.7 28 | with: 29 | mode: sync 30 | target-repo: 'quantecon/lecture-python.zh-cn' 31 | target-language: 'zh-cn' 32 | anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} 33 | github-token: ${{ secrets.GITHUB_TOKEN }} 34 | claude-model: 'claude-opus-4-20250514' # Use a different model 35 | ``` 36 | 37 | ## Available Models 38 | 39 | Check Anthropic's documentation for available models: 40 | https://docs.anthropic.com/en/docs/about-claude/models 41 | 42 | Common options: 43 | - `claude-sonnet-4-5-20250929` - **Recommended** (latest, balanced speed/quality) 44 | - `claude-sonnet-4-20250514` - Previous Sonnet 4 version 45 | - `claude-opus-4-20250514` - Highest quality (slower, more expensive) 46 | - `claude-haiku-4-20250514` - Fastest (lower quality, cheaper) 47 | 48 | ## When to Change Models 49 | 50 | ### Use Claude Opus 51 | - **Highest quality needed**: Critical translations, technical documentation 52 | - **Complex content**: Heavy use of domain-specific terminology 53 | - **Cost is not a concern**: Willing to pay more for best results 54 | 55 | ### Use Claude Haiku 56 | - **Speed is critical**: Large volumes of content 57 | - **Simple content**: Straightforward text without technical terms 58 | - **Cost optimization**: Budget-conscious translations 59 | 60 | ### Use Claude Sonnet (Default) 61 | - **Balanced approach**: Good quality at reasonable cost 62 | - **Most use cases**: General documentation translation 63 | - **Recommended**: Unless you have specific requirements 64 | 65 | ## Testing Different Models 66 | 67 | You can test different models on the same content to compare quality: 68 | 69 | ```yaml 70 | # Test workflow 1: Using Sonnet 71 | - uses: quantecon/action-translation@v0.7 72 | with: 73 | mode: sync 74 | claude-model: 'claude-sonnet-4-20250514' 75 | # ... other parameters 76 | 77 | # Test workflow 2: Using Opus 78 | - uses: quantecon/action-translation@v0.7 79 | with: 80 | mode: sync 81 | claude-model: 'claude-opus-4-20250514' 82 | # ... other parameters 83 | ``` 84 | 85 | ## Cost Comparison 86 | 87 | Approximate costs per 1M tokens (as of October 2025): 88 | 89 | | Model | Input | Output | Use Case | 90 | |-------|-------|--------|----------| 91 | | Haiku | $0.25 | $1.25 | Fast, simple content | 92 | | Sonnet | $3.00 | $15.00 | **Recommended** - balanced | 93 | | Opus | $15.00 | $75.00 | Highest quality | 94 | 95 | *See https://www.anthropic.com/pricing for current pricing* 96 | 97 | ## Example: Upgrading Model Version 98 | 99 | When Anthropic releases a new model version: 100 | 101 | ```yaml 102 | # Old version 103 | claude-model: 'claude-sonnet-4-20250514' 104 | 105 | # New version (when released) 106 | claude-model: 'claude-sonnet-4-20251030' # Example future version 107 | ``` 108 | 109 | ## Troubleshooting 110 | 111 | ### Model Not Found Error 112 | 113 | ``` 114 | 404 {"type":"error","error":{"type":"not_found_error","message":"model: claude-sonnet-4.5-20241022"}} 115 | ``` 116 | 117 | **Solution**: Check the model name is correct. Common mistakes: 118 | - ❌ `claude-sonnet-4.5-20241022` (doesn't exist) 119 | - ✅ `claude-sonnet-4-20250514` (correct) 120 | 121 | ### Model Deprecation 122 | 123 | If Anthropic deprecates a model: 124 | 1. Check deprecation notice in logs 125 | 2. Update `claude-model` to newer version 126 | 3. Test translations with new model 127 | 4. Update workflow 128 | 129 | ## Best Practices 130 | 131 | 1. **Start with Sonnet** - Good balance for most use cases 132 | 2. **Test before switching** - Compare quality on sample content 133 | 3. **Monitor costs** - Check Anthropic console after model changes 134 | 4. **Update gradually** - Test new models before rolling out 135 | 5. **Document your choice** - Note why you chose a specific model 136 | 137 | ## Future Models 138 | 139 | This parameter makes the action future-proof: 140 | - New Claude models can be used immediately 141 | - No code changes required 142 | - Just update the workflow parameter 143 | 144 | --- 145 | 146 | **Recommendation**: Stick with the default `claude-sonnet-4-20250514` unless you have specific requirements. 147 | -------------------------------------------------------------------------------- /tool-test-action-on-github/test-action-on-github-data/README.md: -------------------------------------------------------------------------------- 1 | # Test Action on GitHub - Data Files 2 | 3 | This directory contains test scenarios for validating the translation action against real GitHub repositories. 4 | 5 | ## Structure 6 | 7 | - **workflow-template.yml**: GitHub Actions workflow file for test repositories 8 | - **Base documents**: Starting point for all tests (identical between EN and ZH repos) 9 | - `base-minimal.md` / `base-minimal-zh-cn.md` - Simple 2-section document 10 | - `base-lecture.md` / `base-lecture-zh-cn.md` - Realistic lecture example 11 | - `base-toc.yml` / `base-toc-zh-cn.yml` - Table of contents with 2 files 12 | - `game-theory.md` - New document for testing NEW document mode 13 | - `linear-algebra.md` - Copy of base-lecture for rename testing 14 | 15 | - **Test scenarios**: Modified versions for testing specific changes (24 total) 16 | - **Basic Tests (01-08)**: 17 | - `01-intro-change-minimal.md` - Intro text modified 18 | - `02-title-change-minimal.md` - Title modified 19 | - `03-section-content-minimal.md` - Section content modified 20 | - `04-section-reorder-minimal.md` - Sections reordered 21 | - `05-add-section-minimal.md` - New section added 22 | - `06-delete-section-minimal.md` - Section removed 23 | - `07-subsection-change-minimal.md` - Subsection modified 24 | - `08-multi-element-minimal.md` - Multiple changes 25 | 26 | - **Scientific Content Tests (09-16)**: 27 | - `09-real-world-lecture.md` - Realistic lecture update 28 | - `10-add-subsubsection-lecture.md` - #### subsection added 29 | - `11-change-subsubsection-lecture.md` - #### content changed 30 | - `12-change-code-cell-lecture.md` - Code cell modified 31 | - `13-change-display-math-lecture.md` - Math equations changed 32 | - `14-delete-subsection-lecture.md` - ### deleted 33 | - `15-delete-subsubsection-lecture.md` - #### deleted 34 | - `16-pure-section-reorder-minimal.md` - Pure reorder test 35 | 36 | - **Document Lifecycle Tests (17-20)**: 37 | - `17-new-document-toc.yml` - NEW document added + TOC updated 38 | - `18-delete-document-toc.yml` - Document deleted + TOC updated 39 | - `19-multi-file-minimal.md` + `19-multi-file-lecture.md` - Multiple files 40 | - `20-rename-document-toc.yml` - Document renamed + TOC updated 41 | 42 | - **Edge Cases (21-25)**: 43 | - `21-preamble-only-minimal.md` - Only frontmatter changed 44 | - `22-deep-nesting-lecture.md` - ##### and ###### nesting 45 | - `24-special-chars-lecture.md` - Special characters in headings 46 | - `25-empty-sections-minimal.md` - Sections with no content 47 | 48 | ## File Structure 49 | 50 | Test files use **flat structure** (no `lectures/` folder): 51 | - Source repo: `lecture.md` (root level) 52 | - Target repo: `lecture.md` (root level) 53 | - Workflow configured with `docs-folder: ''` to match root files 54 | 55 | ## Usage 56 | 57 | The test script (`test-action-on-github.sh`) uses these files to: 58 | 59 | ```bash 60 | ./tool-test-action-on-github/test-action-on-github.sh 61 | ``` 62 | 63 | ## Test Scenarios 64 | 65 | ### Phase 1: Basic Structure (Tests 01-08) 66 | 1. **Intro Change** - Only introduction paragraph modified 67 | 2. **Title Change** - Only document title modified 68 | 3. **Section Content** - Content within one section modified 69 | 4. **Section Reorder** - Sections rearranged (tests heading-map) 70 | 5. **Add Section** - New section added to document 71 | 6. **Delete Section** - Existing section removed 72 | 7. **Subsection Change** - Content within subsection modified 73 | 8. **Multi-Element** - Complex change (title + intro + section + new section) 74 | 75 | ### Phase 2: Scientific Content (Tests 09-16) 76 | 9. **Real World** - Realistic lecture update with real content 77 | 10. **Add ####** - Sub-subsection added 78 | 11. **Change ####** - Sub-subsection content modified 79 | 12. **Code Cells** - Code cell comments/titles changed 80 | 13. **Math** - Display math equations changed 81 | 14. **Delete ###** - Subsection removed 82 | 15. **Delete ####** - Sub-subsection removed 83 | 16. **Pure Reorder** - Sections reordered without content changes 84 | 85 | ### Phase 3: Document Lifecycle (Tests 17-20) - NEW! 86 | 17. **NEW Document** - Add new document (game-theory.md) + update _toc.yml 87 | 18. **DELETE Document** - Remove lecture.md + update _toc.yml 88 | 19. **Multiple Files** - Modify both lecture-minimal.md and lecture.md in single PR 89 | 20. **RENAME Document** - Rename lecture.md → linear-algebra.md + update _toc.yml 90 | 91 | ### Phase 4: Edge Cases (Tests 21-25) - NEW! 92 | 21. **Preamble Only** - Only YAML frontmatter changed, no content 93 | 22. **Deep Nesting** - ##### and ###### level subsections 94 | 24. **Special Characters** - Headings with `code`, **bold**, [links], $math$ 95 | 25. **Empty Sections** - Sections with headings but no content 96 | 97 | ## Notes 98 | 99 | - All scenarios use the same base document state 100 | - Minimal scenarios test in isolation 101 | - Real-world scenario tests realistic content 102 | - PRs are created as drafts with `test-translation` label 103 | -------------------------------------------------------------------------------- /dist/heading-map.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"heading-map.js","sourceRoot":"","sources":["../src/heading-map.ts"],"names":[],"mappings":"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"} -------------------------------------------------------------------------------- /tool-onboarding/src/__tests__/constants.test.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Tests for constants.ts - Shared constants and configuration 3 | */ 4 | 5 | import { 6 | DEFAULT_THRESHOLDS, 7 | LANGUAGE_NAMES, 8 | getLanguageName, 9 | I18N_LINE_PATTERNS, 10 | I18N_NAMED_PATTERNS, 11 | STATUS_ICONS, 12 | BLOCK_STATUS_ICONS 13 | } from '../constants'; 14 | 15 | describe('DEFAULT_THRESHOLDS', () => { 16 | it('should have valid code alignment thresholds', () => { 17 | expect(DEFAULT_THRESHOLDS.code.aligned).toBeGreaterThan(0); 18 | expect(DEFAULT_THRESHOLDS.code.aligned).toBeLessThanOrEqual(100); 19 | expect(DEFAULT_THRESHOLDS.code.review).toBeGreaterThan(0); 20 | expect(DEFAULT_THRESHOLDS.code.review).toBeLessThanOrEqual(100); 21 | }); 22 | 23 | it('should have valid prose alignment thresholds', () => { 24 | expect(DEFAULT_THRESHOLDS.prose.aligned).toBeGreaterThan(0); 25 | expect(DEFAULT_THRESHOLDS.prose.aligned).toBeLessThanOrEqual(100); 26 | expect(DEFAULT_THRESHOLDS.prose.review).toBeGreaterThan(0); 27 | expect(DEFAULT_THRESHOLDS.prose.review).toBeLessThanOrEqual(100); 28 | }); 29 | 30 | it('should have aligned threshold >= review threshold', () => { 31 | expect(DEFAULT_THRESHOLDS.code.aligned).toBeGreaterThanOrEqual( 32 | DEFAULT_THRESHOLDS.code.review 33 | ); 34 | expect(DEFAULT_THRESHOLDS.prose.aligned).toBeGreaterThanOrEqual( 35 | DEFAULT_THRESHOLDS.prose.review 36 | ); 37 | }); 38 | }); 39 | 40 | describe('LANGUAGE_NAMES', () => { 41 | it('should have Chinese language mapping', () => { 42 | expect(LANGUAGE_NAMES['zh-cn']).toBe('Simplified Chinese'); 43 | }); 44 | 45 | it('should have Farsi language mapping', () => { 46 | expect(LANGUAGE_NAMES['fa']).toBe('Farsi'); 47 | }); 48 | 49 | it('should have multiple language mappings', () => { 50 | expect(Object.keys(LANGUAGE_NAMES).length).toBeGreaterThan(5); 51 | }); 52 | }); 53 | 54 | describe('getLanguageName', () => { 55 | it('should return full name for known languages', () => { 56 | expect(getLanguageName('zh-cn')).toBe('Simplified Chinese'); 57 | expect(getLanguageName('fa')).toBe('Farsi'); 58 | expect(getLanguageName('ja')).toBe('Japanese'); 59 | }); 60 | 61 | it('should return code for unknown languages', () => { 62 | expect(getLanguageName('unknown')).toBe('unknown'); 63 | expect(getLanguageName('xx')).toBe('xx'); 64 | }); 65 | 66 | it('should handle empty string', () => { 67 | expect(getLanguageName('')).toBe(''); 68 | }); 69 | }); 70 | 71 | describe('I18N_LINE_PATTERNS', () => { 72 | it('should be an array of RegExp', () => { 73 | expect(Array.isArray(I18N_LINE_PATTERNS)).toBe(true); 74 | I18N_LINE_PATTERNS.forEach(pattern => { 75 | expect(pattern).toBeInstanceOf(RegExp); 76 | }); 77 | }); 78 | 79 | it('should match font configuration', () => { 80 | const fontPattern = I18N_LINE_PATTERNS.find(p => 81 | p.test("plt.rcParams['font.family'] = 'sans-serif'") 82 | ); 83 | expect(fontPattern).toBeDefined(); 84 | }); 85 | 86 | it('should match matplotlib font_manager', () => { 87 | const fontManagerPattern = I18N_LINE_PATTERNS.find(p => 88 | p.test("import matplotlib.font_manager as fm") 89 | ); 90 | expect(fontManagerPattern).toBeDefined(); 91 | }); 92 | }); 93 | 94 | describe('I18N_NAMED_PATTERNS', () => { 95 | it('should be an array with name and pattern', () => { 96 | expect(Array.isArray(I18N_NAMED_PATTERNS)).toBe(true); 97 | I18N_NAMED_PATTERNS.forEach(item => { 98 | expect(item).toHaveProperty('name'); 99 | expect(item).toHaveProperty('pattern'); 100 | expect(typeof item.name).toBe('string'); 101 | expect(item.pattern).toBeInstanceOf(RegExp); 102 | }); 103 | }); 104 | 105 | it('should include matplotlib-font pattern', () => { 106 | const fontPattern = I18N_NAMED_PATTERNS.find(p => p.name === 'matplotlib-font'); 107 | expect(fontPattern).toBeDefined(); 108 | }); 109 | }); 110 | 111 | describe('STATUS_ICONS', () => { 112 | it('should have icon for aligned status', () => { 113 | expect(STATUS_ICONS.aligned).toBeDefined(); 114 | expect(typeof STATUS_ICONS.aligned).toBe('string'); 115 | }); 116 | 117 | it('should have icon for differs status', () => { 118 | expect(STATUS_ICONS.differs).toBeDefined(); 119 | expect(typeof STATUS_ICONS.differs).toBe('string'); 120 | }); 121 | 122 | it('should have icon for missing status', () => { 123 | expect(STATUS_ICONS.missing).toBeDefined(); 124 | expect(typeof STATUS_ICONS.missing).toBe('string'); 125 | }); 126 | 127 | it('should have icon for inserted status', () => { 128 | expect(STATUS_ICONS.inserted).toBeDefined(); 129 | expect(typeof STATUS_ICONS.inserted).toBe('string'); 130 | }); 131 | }); 132 | 133 | describe('BLOCK_STATUS_ICONS', () => { 134 | it('should have icon for aligned blocks', () => { 135 | expect(BLOCK_STATUS_ICONS.aligned).toBeDefined(); 136 | }); 137 | 138 | it('should have icon for modified blocks', () => { 139 | expect(BLOCK_STATUS_ICONS.modified).toBeDefined(); 140 | }); 141 | 142 | it('should have icon for inserted-i18n blocks', () => { 143 | expect(BLOCK_STATUS_ICONS['inserted-i18n']).toBeDefined(); 144 | }); 145 | 146 | it('should have icon for missing blocks', () => { 147 | expect(BLOCK_STATUS_ICONS.missing).toBeDefined(); 148 | }); 149 | }); 150 | --------------------------------------------------------------------------------