Skip to content

Fix appVersion IPC, ICS/vCard spec nits, and add ESLint to CI - #450

Merged
tomcardoso merged 1 commit into
mainfrom
fix/pre-1.0-batch-432-440-443
Jul 17, 2026
Merged

Fix appVersion IPC, ICS/vCard spec nits, and add ESLint to CI#450
tomcardoso merged 1 commit into
mainfrom
fix/pre-1.0-batch-432-440-443

Conversation

@tomcardoso

Copy link
Copy Markdown
Owner

Summary

Batches three pre-1.0 audit fixes:

  • window.sourcerer.appVersion is likely empty in packaged builds (broken version link in Settings) #432window.sourcerer.appVersion relied on process.env.npm_package_version, which is only set when launched via an npm script, so it's empty in packaged builds (broken version link + 404 on GitHub in Settings). Now exposed from the main process via app.getVersion() over a synchronous IPC call (app:get-version), matching the pattern the About panel already uses. Not verified against an actual packaged build — that check is called out as needing a human pass.
  • Text/format spec nits: ICS & vCard line folding, vCard TYPE sanitization, astral HTML entities in headlines #440 — three small spec-compliance nits:
    • generateIcal / buildVCard now fold content lines at 75 octets per RFC 5545 / RFC 6350, with continuation lines prefixed by a single space and folds guaranteed not to split multi-byte UTF-8 sequences (new shared foldLine helper in src/main/utils.ts, covered by src/test/fold-line.test.ts).
    • buildVCard's EMAIL;TYPE=... parameter is now sanitized to alphanumerics (falling back to INTERNET) instead of interpolating the raw, user-editable email label.
    • cleanHeadline now decodes numeric/hex HTML entities with String.fromCodePoint instead of String.fromCharCode, so astral codepoints (e.g. emoji in RSS/Google Alerts headlines) decode correctly instead of producing garbage surrogate halves.
  • Add ESLint to CI #443 — added a flat ESLint config (typescript-eslint recommended + eslint-plugin-react-hooks's rules-of-hooks/exhaustive-deps, split Node vs browser globals for src/main+src/preload+src/test vs src/renderer), a lint script, and wired it into ci.yml and preversion. Scripts/build config outside the TS project (scripts/, build/, electron-builder.config.js) are excluded, matching what's already typechecked.

Turning the linter on surfaced a real bug: in ProjectTab.tsx, useListboxKeyboard was called after an early if (!membership) return null;, so the hook was skipped whenever a contact had no project memberships — a genuine conditional-hook violation. Moved the hook (and the option-filtering it depends on) above the early return. Also fixed a handful of mechanical findings (an unused let, a dead assignment, an unnecessary regex escape, unused type imports, a stale/unused test mock) and left the remaining exhaustive-deps findings as warnings, since they don't block CI and each would need individual judgement calls about effect timing.

Test plan

  • npm run typecheck passes
  • npm run lint passes (0 errors, 7 pre-existing exhaustive-deps warnings, non-blocking)
  • npm test — 490/490 passing, including new foldLine coverage
  • Verify appVersion renders correctly in an installed/packaged build (not verifiable from source)

Closes #432
Closes #440
Closes #443

🤖 Generated with Claude Code

- appVersion now comes from app.getVersion() via IPC (sendSync) instead of
  process.env.npm_package_version, which is empty in packaged builds (#432)
- Fold ICS/vCard content lines at 75 octets per RFC 5545/6350, sanitize the
  vCard EMAIL TYPE parameter, and decode astral HTML entities with
  String.fromCodePoint instead of String.fromCharCode (#440)
- Add flat ESLint config (typescript-eslint + react-hooks) and wire it into
  CI and preversion; fix the lint findings it turned up, including a real
  conditional hook call in ProjectTab (#443)

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@tomcardoso
tomcardoso merged commit c1c8f25 into main Jul 17, 2026
1 check passed
@tomcardoso
tomcardoso deleted the fix/pre-1.0-batch-432-440-443 branch July 17, 2026 16:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant