From 4b40b25e538b6f5932d255a0f3d123257f866f3f Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Sat, 19 Sep 2026 08:47:26 +0900 Subject: [PATCH] fix(site): stop the landing build from depending on hoisted Node types MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hero typed its timer ref with NodeJS.Timeout, which only resolves when @types/node is visible from an ancestor node_modules. The deploy job installs site dependencies alone, so tsc -b failed with TS2503 and the landing site has not been redeployed since. Use ReturnType and record the measured deploy blocker plus the runner's missing Python in the map. ๐Ÿ’˜ Generated with Crush Assisted-by: Crush:deepseek-v4.1-flash --- docs/map/11-gap-backlog.md | 4 +++- site/src/sections/Hero.tsx | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/map/11-gap-backlog.md b/docs/map/11-gap-backlog.md index d3a5462..eef0ebe 100644 --- a/docs/map/11-gap-backlog.md +++ b/docs/map/11-gap-backlog.md @@ -23,7 +23,9 @@ Legend: `[ ]` open ยท `[~]` in progress ยท `[!]` blocked externally ยท `[x]` res | GAP-QA-01 | Quality | Extreme Red Team: headful end-to-end bug hunting across real desktop Electron, Web Next.js, and CI pipelines. | `red_team_log.md`, `tests/e2e/red_team_cycle*.spec.ts`, `apps/web/e2e/red_team_cycle4_web.spec.ts` | `[x]` 2026-09-15: 18 scenarios executed, 14 defects caught and 100% resolved (infinite chunking loop DEF-008, IPC signature mismatch DEF-004, markdown editor typing rollback DEF-006, Web RSC Link serialization DEF-012, secret scanner lookahead DEF-013, etc.). All 18 scenarios GREEN with zero regressions. | | GAP-REL-01 | Release | Official release publication to Forgejo and active public download center deployment. | `scripts/ci/publish-forgejo-release.mjs`, `apps/web/src/app/download/page.tsx`, `site/src/sections/Download.tsx`, `apps/web/e2e/red_team_cycle4_web.spec.ts` | `[~]` 2026-09-15: v1.1.0 release assets (`D3RO-Voice-Setup-1.1.0-x64.exe`, `.blockmap`, `latest.yml`, `update-policy.json`) published to canonical Forgejo registry and release hub. 2026-09-16: the published 1.1.0 installer carries no Authenticode signature, so it does not satisfy the release policy; product version moved to `1.2.0` and publication must come from CI with the signing gate GREEN. Download centers in `apps/web` (`/download`) and `site` (`#download`) link the canonical Forgejo feed. 2026-09-19: `1.3.7` (overlay fix) is published to the canonical updater feed (`latest.yml` = 1.3.7, 90.6MiB); the CI signing gate that blocks tag-driven publication is still unresolved, so this went out through the local updater path (GAP-REL-06). | | GAP-REL-08 | Release | ๋‹ค์šด๋กœ๋“œ ์„ผํ„ฐ๊ฐ€ **์กด์žฌํ•˜์ง€ ์•Š๋Š” ์„ค์น˜ ํŒŒ์ผ**์„ ๊ฐ€๋ฆฌ์ผฐ๋‹ค. `apps/web/src/lib/desktop-release.ts`์™€ `site/src/release.ts`์˜ `DESKTOP_VERSION`์ด `1.2.0`์— ๋ฉˆ์ถฐ ์žˆ์–ด ์„ค์น˜ URL์ด `D3RO-Voice-Setup-1.2.0-x64.exe`์˜€๊ณ , ๊ทธ ๊ฒฝ๋กœ๋Š” ํ”ผ๋“œ์—์„œ 404๋‹ค(์‹ค์ธก: 1.2.0=404, 1.3.7=206). `version:sync`๊ฐ€ ์ด ๋‘ ํ‘œ๋ฉด์„ ๋ฎ์ง€ ์•Š์•„ ๊ณ„์† ์–ด๊ธ‹๋‚ฌ๋‹ค. | `scripts/ci/sync-version.mjs`, `apps/web/src/lib/desktop-release.ts`, `site/src/release.ts` | `[x]` 2026-09-19: ๋‘ ๋‹ค์šด๋กœ๋“œ ๊ณ„์•ฝ ํŒŒ์ผ์„ `sync-version.mjs` ๋Œ€์ƒ์— ์ถ”๊ฐ€ํ•ด ๋ฒ„์ „ยท๋ฆด๋ฆฌ์Šค์ผ์ด SSOT์—์„œ ์ž๋™ ๋ฐ˜์˜๋˜๋„๋ก ํ•˜๊ณ , ํ˜„์žฌ ๊ฐ’(1.3.7 / 2026-09-19)์œผ๋กœ ์ •์ •ํ–ˆ๋‹ค. `version:check`ยทtypecheckยทsite ๋นŒ๋“œ GREEN. | -| GAP-REL-09 | Release | ๋žœ๋”ฉ ์‚ฌ์ดํŠธ๊ฐ€ **์žฌ๋ฐฐํฌ๋˜์ง€ ์•Š๋Š”๋‹ค**. `deploy` ์›Œํฌํ”Œ๋กœ๊ฐ€ main push๋งˆ๋‹ค ์‹คํŒจํ•˜๊ณ  `https://d3ro.chanpaca.net/release-identity.json`์ด 404๋‹ค(๊ณต๊ฐœ ๋ฒ„์ „ ๊ฒ€์ฆ ๋ถˆ๊ฐ€). ์›Œํฌํ”Œ๋กœ๋Š” Cloudflare Pages ํ† ํฐ ์‹œํฌ๋ฆฟ์ด ์—†์œผ๋ฉด `exit 1`๋กœ ์ค‘๋‹จํ•œ๋‹ค. | `.forgejo/workflows/deploy-site.yml` | `[!]` 2026-09-19: Forgejo์— `CF_API_TOKEN`(๋˜๋Š” `CLOUDFLARE_API_TOKEN`) + `CF_ACCOUNT_ID`๋ฅผ ๋“ฑ๋กํ•˜๊ณ  `deploy-site.yml`์„ ์ˆ˜๋™ ์‹คํ–‰ํ•œ๋‹ค. ๊ทธ๋•Œ๊นŒ์ง€ GAP-REL-08์˜ ๋‹ค์šด๋กœ๋“œ ํŽ˜์ด์ง€ ์ˆ˜์ •์€ ๋กœ์ปฌ ๋นŒ๋“œ๋กœ๋งŒ ํ™•์ธ๋œ๋‹ค. | +| GAP-REL-09 | Release | ๋žœ๋”ฉ ์‚ฌ์ดํŠธ๊ฐ€ **์žฌ๋ฐฐํฌ๋˜์ง€ ์•Š๋Š”๋‹ค**. `deploy` ์›Œํฌํ”Œ๋กœ๊ฐ€ main push๋งˆ๋‹ค ์‹คํŒจํ•œ๋‹ค. ์‹ค์ธก ์›์ธ(run#66 ๋กœ๊ทธ): `site/src/sections/Hero.tsx`๊ฐ€ ํƒ€์ด๋จธ ref๋ฅผ `NodeJS.Timeout`์œผ๋กœ ํƒ€์ดํ•‘ํ•ด `@types/node` ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ ํ•„์š”ํ–ˆ๊ณ , ๋ฐฐํฌ ์žก์€ `npm ci --prefix site`๋งŒ ํ•˜๋ฏ€๋กœ ์กฐ์ƒ `node_modules`์˜ hoisted ํƒ€์ž…์ด ์—†์–ด `tsc -b`๊ฐ€ `TS2503: Cannot find namespace 'NodeJS'`๋กœ ์‹คํŒจํ•œ๋‹ค. ๊ทธ๋ž˜์„œ `https://d3ro.chanpaca.net/release-identity.json`์ด 404๋‹ค(๊ณต๊ฐœ ๋ฒ„์ „ ๊ฒ€์ฆ ๋ถˆ๊ฐ€). | `.forgejo/workflows/deploy-site.yml`, `site/src/sections/Hero.tsx` | `[x]` 2026-09-19: ref๋ฅผ `ReturnType`์œผ๋กœ ๋ฐ”๊ฟ” hoisted ํƒ€์ž… ์˜์กด์„ ์ œ๊ฑฐํ–ˆ๋‹ค(๊ฒฉ๋ฆฌ `--typeRoots`๋กœ CI ์กฐ๊ฑด ์žฌํ˜„ โ†’ ์ˆ˜์ • ์ „ TS2503, ์ˆ˜์ • ํ›„ clean). ๋ฐฐํฌ ์žก์ด Cloudflare Pages ๋‹จ๊ณ„๊นŒ์ง€ ์ง„ํ–‰๋˜๋Š”์ง€ ๋‹ค์Œ run์œผ๋กœ ํ™•์ธํ•œ๋‹ค. | +| GAP-REL-09b | Release | ์œ„ ๋นŒ๋“œ๋ฅผ ํ†ต๊ณผํ•œ ๋’ค์—๋„ `deploy`๊ฐ€ ์‹คํŒจํ•˜๋ฉด ๋‹ค์Œ ์›์ธ์€ Cloudflare Pages ์‹œํฌ๋ฆฟ์ด๋‹ค. ์›Œํฌํ”Œ๋กœ๋Š” `CF_API_TOKEN`(๋˜๋Š” `CLOUDFLARE_API_TOKEN`)์ด ์—†์œผ๋ฉด `exit 1`๋กœ ์ค‘๋‹จํ•œ๋‹ค. | `.forgejo/workflows/deploy-site.yml` | `[ ]` 2026-09-19: Forgejo์— `CF_API_TOKEN` + `CF_ACCOUNT_ID`๋ฅผ ๋“ฑ๋กํ•˜๊ณ  `deploy-site.yml`์„ ์ˆ˜๋™ ์‹คํ–‰ํ•ด ์‚ฌ์ดํŠธ๋ฅผ ์žฌ๋ฐฐํฌํ•œ๋‹ค. | +| GAP-REL-10 | Release | ํƒœ๊ทธ ํŒŒ์ดํ”„๋ผ์ธ์€ ์„œ๋ช… ๊ฐ€๋“œ์— ๋„๋‹ฌํ•˜๊ธฐ **์ „์—** sidecar ๋‹จ๊ณ„์—์„œ ์ฃฝ๋Š”๋‹ค. Forgejo ์ž์ฒด ๋Ÿฌ๋„ˆ(`yunchan-win`)์— Python 3.11+๊ฐ€ ์—†์–ด `sidecar:setup`("Python 3.11+ ๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค") โ†’ `sidecar:build` โ†’ `verify-sidecar-bundle.mjs`๊ฐ€ ์—ฐ์‡„ ์‹คํŒจํ•œ๋‹ค(์‹ค์ธก: `v1.3.7` release-windows run#65 ๋กœ๊ทธ). ์ฆ‰ CI ๊ฒŒ์‹œ๋Š” ์ธ์ฆ์„œ ์ด์ „์— ๋Ÿฌ๋„ˆ ํ™˜๊ฒฝ์—์„œ ๋จผ์ € ๋ง‰ํ˜€ ์žˆ๋‹ค. | `.forgejo/workflows/release.yml`, `.forgejo/workflows/portable.yml`, `apps/desktop/scripts/setup-sidecar.mjs` | `[!]` 2026-09-19: ๋Ÿฌ๋„ˆ์— Python 3.11+๋ฅผ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜ ์›Œํฌํ”Œ๋กœ์— `actions/setup-python` ๋‹จ๊ณ„๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. ๊ทธ๋•Œ๊นŒ์ง€ ๊ฒŒ์‹œ ์ •๋ณธ์€ ๋กœ์ปฌ `release:updater`/`release:portable` ๊ฒฝ๋กœ๋‹ค(GAP-REL-06). | | GAP-REL-02 | Release | Windows stable publication needs an external public-trust Authenticode PFX, its password, the exact signer subject, and a Forgejo token, none of which live in the repository. | `.forgejo/workflows/release.yml`, `.gitlab-ci.yml`, `scripts/ci/set-forgejo-secrets.mjs`, `scripts/ci/verify-windows-release-artifact.ps1` | `[!]` 2026-09-18 measured: the Forgejo repo had **zero** Actions secrets; `FORGEJO_TOKEN` is registered now (2026-09-18) but `WIN_CSC_*` still have no values, so `v1.2.0` (run 49) and `v1.3.0` (run 51) both failed at the signing guard and **no updater-feed release has been published since `1.1.0`**. Inject the four secrets (`WIN_CSC_LINK`, `WIN_CSC_KEY_PASSWORD`, `WIN_CSC_EXPECTED_SIGNER_SUBJECT`, `FORGEJO_TOKEN`) with `npm run release:secrets` (check: `npm run release:secrets:check`), then re-run `release.yml` for the `v1.3.0` tag via `workflow_dispatch` (tags are immutable). **2026-09-19 ์ •์ •**: CI ์„œ๋ช… ๊ฒŒ์ดํŠธ๋Š” ์—ฌ์ „ํžˆ ๋ง‰ํ˜€ ์žˆ์ง€๋งŒ, updater feed์—๋Š” `1.3.2`~`1.3.7`์ด ๋กœ์ปฌ `release:updater` ๊ฒฝ๋กœ๋กœ ๊ฒŒ์‹œ๋˜์–ด ์žˆ๋‹ค(GAP-REL-06). | | GAP-REL-06 | Release | ์„œ๋ช… ์ธ์ฆ์„œ๊ฐ€ ์—†์–ด stable(`latest`) ์ฑ„๋„์— **๋ฌด์„œ๋ช…** ์„ค์น˜๋ณธ์„ ๊ฒŒ์‹œํ–ˆ๋‹ค. electron-updater๋Š” `app-update.yml`์— `publisherName`์ด ์—†์œผ๋ฉด ์„œ๋ช… ๊ฒ€์ฆ์„ ๊ฑด๋„ˆ๋›ฐ๋ฏ€๋กœ ์„ค์น˜๋Š” ๋™์ž‘ํ•˜์ง€๋งŒ, SmartScreen ํ‰ํŒ์€ ๋ฒ„์ „๋งˆ๋‹ค 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค. | `scripts/ci/publish-updater-release.mjs`, `release/update-policy.json`, `.forgejo/workflows/release.yml` | `[!]` 2026-09-18: `1.3.2`๋ฅผ `--ack-unsigned`(๋ช…์‹œ์  ์Šน์ธ ํ”Œ๋ž˜๊ทธ)๋กœ ๊ฒŒ์‹œ. **2026-09-19: `1.3.7`๋„ ๊ฐ™์€ ๊ฒฝ๋กœ๋กœ ๊ฒŒ์‹œ**(`npm run release:updater -- --ack-unsigned`, ์„ค์น˜๋ณธ 90.6MiB, `latest.yml`=1.3.7, ์„ค์น˜๋ณธ sha512๊ฐ€ ํ”ผ๋“œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ์ผ์น˜). ์ธ์ฆ์„œ ํ™•๋ณด ์‹œ ๋” ๋†’์€ ๋ฒ„์ „์œผ๋กœ ์„œ๋ช… ๊ฒŒ์‹œํ•˜์—ฌ ๋Œ€์ฒดํ•˜๊ณ , ์ด ์˜ˆ์™ธ๋ฅผ ์ œ๊ฑฐํ•œ๋‹ค. | | GAP-REL-07 | Release | ํŒจํ‚ค์ง•๋œ `better-sqlite3`๊ฐ€ ํ˜ธ์ŠคํŠธ Node ABI์—ฌ์„œ `1.3.2` ์„ค์น˜๋ณธ์ด ์‹œ์ž‘ ์ฆ‰์‹œ ์ฃฝ์—ˆ๋‹ค(NODE_MODULE_VERSION 131 vs 130). ์›์ธ: ๋กœ์ปฌ `npm install`์ด ๋„ค์ดํ‹ฐ๋ธŒ ๋ชจ๋“ˆ์„ Node์šฉ์œผ๋กœ ์žฌ๋นŒ๋“œํ–ˆ๊ณ  ํŒจํ‚ค์ง•์ด ์žฌ๋นŒ๋“œ๋ฅผ ๊ฑด๋„ˆ์—ˆ๋‹ค. | `scripts/ci/verify-native-abi.mjs`, `scripts/ci/fix-native-abi.mjs`, `.gitlab-ci.yml`/`.forgejo`/`.github` ํŒจํ‚ค์ง• ๋‹จ๊ณ„ | `[x]` 2026-09-18: ํŒจํ‚ค์ง• ํ›„ Electron ABI๋ฅผ ๊ฒ€์ฆํ•˜๊ณ , ๊ฒ€์ฆ๋œ ํŠธ๋ฆฌ์—์„œ๋งŒ ์„ค์น˜๋ณธ์„ ์ƒ์„ฑ(`--prepackaged`)ํ•œ๋‹ค. `1.3.3`์€ ์„ค์น˜๋ณธ์—์„œ ์ถ”์ถœํ•œ ๋ฐ”์ด๋„ˆ๋ฆฌ๋กœ ์žฌ๊ฒ€์ฆ GREEN. | diff --git a/site/src/sections/Hero.tsx b/site/src/sections/Hero.tsx index 3e0117a..550d619 100644 --- a/site/src/sections/Hero.tsx +++ b/site/src/sections/Hero.tsx @@ -15,7 +15,7 @@ export function Hero() { const [typedRaw, setTypedRaw] = useState('') const [typedClean, setTypedClean] = useState('') const [waveLevels, setWaveLevels] = useState([0.3, 0.5, 0.8, 1, 0.9, 0.7, 0.4, 0.6, 0.3]) - const timerRef = useRef(null) + const timerRef = useRef | null>(null) const sampleRawText = locale === 'ko' ? '์–ด... ์ด๋ฒˆ ํ”„๋กœ์ ํŠธ ๋ฐฐํฌ๋Š” ๋‹ค์Œ ์ฃผ ๊ธˆ์š”์ผ๊นŒ์ง€๋กœ ์žก์œผ๋ฉด ๋  ๊ฒƒ ๊ฐ™์•„์š”.'