Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
Modern React Applications Monorepo - RateWise, NihonName, Quake-School, haotool | React 19 + TypeScript 5.9 + Vite 7.3 | 1000+ tests, 92%+ coverage | GPL-3.0
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
haotool Apps 是一個專業的 pnpm Monorepo,包含多個高品質的 React 19 應用程式。所有應用程式共享統一的工程標準、CI/CD 管線和開發工具鏈。 「HAO」取自中文「好」的拼音,我們的核心理念是打造真正的「好工具」。 基於臺灣銀行牌告匯率的即時匯率 PWA 應用,顯示實際買賣價(非中間價) • 台銀實際賣出價:顯示真正換匯成本,非市場中間價 • 18 種貨幣、4 種匯率類型(現金/即期買入賣出) • 即時匯率:每 5 分鐘同步臺灣銀行牌告匯率 • 趨勢圖表:30 天歷史匯率走勢視覺化 • PWA 支援:可安裝至手機,支援離線使用 • 收藏管理:自訂常用貨幣快速存取 • 程序化 SEO:249 個可索引 SEO path(幣對頁 + 金額頁) [README 설치·사용 부분 발췌] Quick StartREADME 전문 보기 ↗
Modern React Applications Monorepo
haotool Apps 是一個專業的 pnpm Monorepo,包含多個高品質的 React 19 應用程式。所有應用程式共享統一的工程標準、CI/CD 管線和開發工具鏈。
「HAO」取自中文「好」的拼音,我們的核心理念是打造真正的「好工具」。
| 應用 | 描述 | 狀態 | 連結 |
|---|---|---|---|
| RateWise | 台銀即時匯率換算 PWA,支援 17 種外幣與 TWD | Live | app.haotool.org/ratewise |
| NihonName | 日本名字產生器,探索皇民化歷史 | Live | app.haotool.org/nihonname |
| Quake-School | 互動式地震科學教育平台 | Live | app.haotool.org/quake-school |
| Park Keeper | 停車場導航工具,GPS 指引 + 多語言(i18n) | Live | app.haotool.org/park-keeper |
| Split Meow | 貓咪主題旅遊帳單分攤計算機,支援費用分類與分享 | Live | app.haotool.org/split-meow |
| A320neo Flight Deck | 物理驅動的 A320neo 互動駕駛艙飛行模擬(WebGL) | Dev | 本機 pnpm --filter @app/a320-flight-deck dev |
| StarPuff | 吸入果凍怪、擊敗果凍王的直向 Boss Rush 小遊戲 | Live | app.haotool.org/starpuff |
| PaperTrade | 零風險模擬合約交易所,串接真實加密貨幣行情 | Live | app.haotool.org/papertrade |
| haotool | 專案展示平台,3D 互動首頁 | Live | app.haotool.org |
基於臺灣銀行牌告匯率的即時匯率 PWA 應用,顯示實際買賣價(非中間價)
FX_V3_PUBLIC=true):以支付幣別 → 取得幣別表達方向,保留來源買賣側、條件與 SHA-256 release manifest;Open Data 與 App 均使用 v3。回滾只需以一行 PR 關閉此開關,data 發佈 gate 獨立運作探索 1940 年代台灣皇民化運動的歷史改姓對照
互動式地震科學教育網站
GPS 輔助的停車場路徑指引工具
貓咪主題的旅遊帳單分攤工具
3D 互動展示平台,介紹所有專案
| 類別 | 技術 |
|---|---|
| 框架 | React 19.2 + TypeScript 5.9 |
| 建置工具 | Vite 8.0 + vite-react-ssg |
| 樣式 | Tailwind CSS 3.4 |
| 測試 | Vitest 4.1 + Playwright 1.57 |
| 套件管理 | pnpm 9.10.0 (Monorepo) |
| CI/CD | GitHub Actions (13 workflows) |
| 部署 | Cloudflare Pages + Worker |
| 安全 | Gitleaks CLI + Trivy + SARIF |
| 指標 | 數值 |
|---|---|
| 測試數量 | 1700+ |
| 測試覆蓋率 | 92%+ |
| TypeScript | Strict Mode |
| ESLint | 0 警告 |
| Lighthouse | 95+ 全類別 |
| CI 管線 | 13 個 workflow |
# 複製儲存庫
git clone https://github.com/haotool/app.git
cd app
# 安裝依賴
pnpm install
# 啟動所有應用開發模式
pnpm dev
# 或啟動特定應用
pnpm --filter @app/ratewise dev # RateWise (http://localhost:4173)
pnpm --filter @app/nihonname dev # NihonName (http://localhost:3002)
pnpm --filter @app/quake-school dev # Quake-School (http://localhost:3003)
pnpm --filter @app/park-keeper dev # Park Keeper (http://localhost:3004)
pnpm --filter @app/split-meow dev # Split Meow (http://localhost:3005)
pnpm --filter @app/a320-flight-deck dev # A320neo Flight Deck (http://localhost:3010)
pnpm --filter @app/starpuff dev # StarPuff (http://localhost:3007)
pnpm --filter @app/papertrade dev # PaperTrade (http://localhost:5173)
pnpm --filter @app/haotool dev # haotool (http://localhost:3000)
# 建置所有應用
pnpm build
# 執行測試
pnpm test
# TypeScript 檢查
pnpm typecheck
# ESLint 檢查
pnpm lint
# 每個 PR 都要建立 changeset,描述使用者可見影響
pnpm changeset
# release PR 由 GitHub Actions 自動建立
pnpm changeset:status
Release workflow 以 pnpm changeset:version 作為版本 SSOT,並由
scripts/get-release-metadata.mjs --changed 產生 release tag 與 GitHub
release 清單。禁止手動修改版本號、手動編輯 CHANGELOG,或在 CI 內直接呼叫
pnpm changeset tag 建 tag;CI 內部 tag push 會以 HUSKY=0 單次推送,避免重複觸發
pre-push hook。
release PR 由 release.yml 全自動合併:因 GITHUB_TOKEN 建立的 PR 其
pull_request CI 停在 approval-required 狀態(GitHub 防遞迴),workflow 會核准
pending 的 pull_request run、等待 Quality Checks 通過後直接合併(仍受 branch
protection 把關),並補派 main 上的 release.yml / ci.yml 完成 tags 與部署,
全程無需人工介入。若設定 RELEASE_PAT secret(fine-grained PAT,Actions/Contents/
Pull requests Read&Write),changesets 會改以 PAT 開 PR,CI 全原生觸發。
正式站由 GitHub Actions Deploy Cloudflare Pages 在 main push 時自動部署至 Cloudflare Pages
haotool-static,並經 security-headers Worker 的 STATIC_ORIGIN 對外提供。合併一般 PR 後若會再合併
changesets release PR,需先確認較早的 production deployment 已完成,避免舊 SHA 在 release
SHA 之後才變成 active,造成正式站版本回退。Release 後以
app-version、GitHub deployment status 與 live precache 驗證作為完成證據。
Live precache 驗證涵蓋全部 SW 清單,僅原始 URL 404 以 15/30/60/75 秒間隔重試(最多 5 次);最終失敗輸出原 URL 與 querystring 狀態,querystring 成功仍判失敗。每個 HTTP 請求上限 10 秒。
Cloudflare Pages 的公開流量均先經 security-headers Worker;Pages main push
會先部署 candidate branch,通過 contract-only parity 後才更新 production。只有完成 Preview
與 Production parity 驗證後,才設定 Worker 的 STATIC_ORIGIN。Cloudflare rating-api
與 KV 維持獨立;Pages GitHub Actions 的 Cloudflare API token 僅在實際部署 step 使用。
haotool-app/
├── apps/
│ ├── ratewise/ # 匯率換算工具
│ ├── nihonname/ # 日本名字產生器
│ ├── quake-school/ # 地震知識小學堂
│ ├── park-keeper/ # 停車場導航工具
│ ├── split-meow/ # 貓咪分帳計算機
│ ├── a320-flight-deck/ # A320neo 飛行模擬(React + three.js)
│ ├── starpuff/ # 直向 Boss Rush 小遊戲
│ ├── papertrade/ # 模擬合約交易所
│ ├── haotool/ # 專案展示平台
│ └── shared/ # 共用模組
├── docs/ # 文檔
├── scripts/ # 自動化腳本
├── .github/
│ └── workflows/ # CI/CD 管線
│ ├── ci.yml # 主要 CI 流程
│ ├── release.yml # 版本發布
│ ├── seo-audit.yml # SEO 審查
│ ├── seo-production.yml # 生產環境 SEO
│ ├── ratewise-production-governance.yml # RateWise 生產治理檢查
│ ├── update-committed-seo-files.yml # SEO 產出物同步
│ ├── update-historical-rates.yml # 歷史匯率更新
│ ├── update-latest-rates.yml # 最新匯率更新
│ ├── update-moneybox-rates.yml # MoneyBox 匯率更新
│ ├── publish-fx-v3.yml # 匯率 v3 發布(reusable,預設關閉)
│ └── update-seo-rate-examples.yml # SEO 範例匯率更新
├── package.json # Monorepo 根配置
├── pnpm-workspace.yaml # pnpm workspace 配置
└── tsconfig.base.json # 共用 TypeScript 配置
| 文檔 | 描述 |
|---|---|
| AGENTS.md | Agent 工具與工作流程 |
| LINUS_GUIDE.md | Linus 風格開發指南 |
| CONTRIBUTING.md | 貢獻指南 |
| CODE_OF_CONDUCT.md | 行為準則 |
| SECURITY.md | 安全政策 |
| COMMIT_CONVENTION.md | 提交規範 |
歡迎提交 Issue 和 Pull Request!請先閱讀 貢獻指南。
本專案採用 GPL-3.0 授權。
haotool Apps is a professional pnpm Monorepo containing multiple high-quality React 19 applications. All applications share unified engineering standards, CI/CD pipelines, and development toolchains.
"HAO" comes from the Chinese word "好" (good). Our core philosophy is to build truly good tools.
| App | Description | Status | Link |
|---|---|---|---|
| RateWise | Taiwan Bank exchange rate PWA, 17 foreign currencies + TWD | Live | app.haotool.org/ratewise |
| NihonName | Japanese name generator, historical exploration | Live | app.haotool.org/nihonname |
| Quake-School | Interactive earthquake science education | Live | app.haotool.org/quake-school |
| Park Keeper | Parking lot navigator with GPS compass + i18n | Live | app.haotool.org/park-keeper |
| Split Meow | Cat-themed trip expense splitter with share + emoji | Live | app.haotool.org/split-meow |
| A320neo Flight Deck | Physics-driven interactive A320neo flight simulator (WebGL) | Dev | local pnpm --filter @app/a320-flight-deck dev |
# Clone repository
git clone https://github.com/haotool/app.git
cd app
# Install dependencies
pnpm install
# Start development
pnpm dev
Every PR must include a changeset. GitHub Actions creates the release PR with
pnpm changeset:version; release tags and GitHub releases are generated from
scripts/get-release-metadata.mjs --changed.
Production is deployed automatically to Cloudflare Pages haotool-static by the
Deploy Cloudflare Pages GitHub Actions workflow on every main push, and served through the
security-headers Worker STATIC_ORIGIN. Before merging a release PR
right after another main PR, confirm the earlier production deployment has
finished so an older SHA cannot become active after the release SHA.
RateWise generated files are bucketed by package scripts:
prebuild runs deterministic generation and verification only,
refresh:data explicitly updates live snapshots, and
refresh:fallback-rates is the only script that writes the committed fallback
rate snapshot. Local tool output such as lighthouse-report.json and
*.tsbuildinfo must remain untracked.
This project is licensed under GPL-3.0.
Built with ❤️ by haotool
共用 setup-playwright 的 OS 套件安裝必須等待 install-deps 完整結束後才重試;禁止以非 root 的外層 timeout 中斷 root apt,避免遺留鎖。CI 呼叫步驟使用 timeout-minutes: 15,逾時直接失敗,不繼續重試。瀏覽器下載沿用 Playwright 原生 120 秒 socket 逾時,禁止以整體下載秒數中斷仍有進度的安裝。共用 action 變更必須觸發全部使用它的 app PR smoke。依據:GitHub step timeout。
其他 app 的 PR smoke 與 main/full E2E 使用固定版 mcr.microsoft.com/playwright:v1.61.1-noble,沿用預裝瀏覽器及 OS 套件,避免臨時 apt mirror 安裝阻斷。image 版本必須與鎖定的 Playwright 版本一致,由 root 回歸測試守門;CI workflow 變更觸發全部受影響 app smoke。依據:Playwright Docker。
| StarPuff |
| Vertical boss-rush action mini game with Phaser |
| Live |
| app.haotool.org/starpuff |
| PaperTrade | Risk-free crypto perpetual paper-trading exchange | Live | app.haotool.org/papertrade |
| haotool | Project showcase with 3D interactive homepage | Live | app.haotool.org |