Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: true
contact_links:
- name: Contributing guide
url: https://github.com/iagommendes/coderkeys/blob/main/CONTRIBUTING.md
about: Read how to contribute lessons, locales, and code
76 changes: 76 additions & 0 deletions .github/ISSUE_TEMPLATE/new-lesson.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: New lesson proposal
description: Propose a new typing lesson for an existing track
title: "[Lesson] "
labels: ["content"]
body:
- type: markdown
attributes:
value: |
Thanks for proposing a lesson! See [CONTRIBUTING-CONTENT.md](https://github.com/iagommendes/coderkeys/blob/main/content/CONTRIBUTING-CONTENT.md) for the file format.

- type: dropdown
id: track
attributes:
label: Track
options:
- programmers
- technical-writers
- devops
- data-science
- legal-translators
- other
validations:
required: true

- type: input
id: module
attributes:
label: Module
description: e.g. syntax-brackets, docker-cli
validations:
required: true

- type: dropdown
id: locale
attributes:
label: Locale
options:
- en-US
- pt-BR
- es-ES
validations:
required: true

- type: input
id: title
attributes:
label: Lesson title
validations:
required: true

- type: textarea
id: text
attributes:
label: Text to type
description: The exact passage users will practice (min 20 characters)
validations:
required: true

- type: dropdown
id: mode
attributes:
label: Mode
options:
- code
- prose
- translation
validations:
required: true

- type: input
id: difficulty
attributes:
label: Difficulty (1-5)
placeholder: "3"
validations:
required: true
33 changes: 33 additions & 0 deletions .github/ISSUE_TEMPLATE/new-locale.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: New locale request
description: Request or offer a new UI or content language
title: "[Locale] "
labels: ["i18n"]
body:
- type: markdown
attributes:
value: |
See [docs/ADDING-LOCALE.md](https://github.com/iagommendes/coderkeys/blob/main/docs/ADDING-LOCALE.md) for implementation steps.

- type: input
id: locale
attributes:
label: Locale code
description: e.g. es-ES, fr-FR, de-DE
placeholder: es-ES
validations:
required: true

- type: checkboxes
id: scope
attributes:
label: Scope
options:
- label: UI translation (interface strings)
- label: Lesson content translation
- label: I can contribute the translations myself

- type: textarea
id: notes
attributes:
label: Additional notes
description: Why this locale matters, RTL requirements, etc.
25 changes: 25 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
## Summary

<!-- What does this PR change and why? -->

## Type of change

- [ ] Bug fix
- [ ] New lesson(s) or track
- [ ] UI / feature
- [ ] Documentation
- [ ] CI / tooling

## Checklist

- [ ] `pnpm typecheck` passes
- [ ] `pnpm test` passes
- [ ] `pnpm validate-content` passes (if `content/` changed)
- [ ] `pnpm check-i18n` passes (if `i18n/` changed)
- [ ] Lesson IDs follow `001-slug` pattern
- [ ] New lessons added to `content/manifest.json`
- [ ] No secrets, credentials, or offensive content in lesson text

## Screenshots (if UI changes)

<!-- Optional -->
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,25 @@ jobs:
- run: pnpm check-i18n

- run: pnpm build

e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- run: pnpm install --frozen-lockfile

- run: pnpm --filter @coderkeys/schemas build && pnpm --filter @coderkeys/engine build

- run: pnpm build

- run: pnpm --filter @coderkeys/web exec playwright install --with-deps chromium

- run: pnpm test:e2e
63 changes: 63 additions & 0 deletions .github/workflows/content-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
name: Content preview

on:
pull_request:
paths:
- 'content/**'

permissions:
pull-requests: write
contents: read

jobs:
preview:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- run: pnpm install --frozen-lockfile

- name: Generate content preview
run: |
pnpm --filter @coderkeys/schemas build
pnpm exec tsx scripts/content-preview.ts > content-preview.md
env:
GITHUB_BASE_REF: ${{ github.base_ref }}

- uses: actions/github-script@v7
with:
script: |
const fs = require('node:fs');
const body = fs.readFileSync('content-preview.md', 'utf8');
const marker = '<!-- coderkeys-content-preview -->';
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.find((c) => c.body?.includes(marker));
const fullBody = `${marker}\n${body}`;
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body: fullBody,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: fullBody,
});
}
41 changes: 41 additions & 0 deletions .github/workflows/desktop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Desktop build

on:
push:
branches: [main]
tags: ['v*']
pull_request:
branches: [main]
paths:
- 'src-tauri/**'
- 'apps/web/**'
- 'packages/**'

jobs:
build-linux:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf

- uses: dtolnay/rust-toolchain@1.88

- run: pnpm install --frozen-lockfile

- uses: tauri-apps/tauri-action@v0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
projectPath: src-tauri
args: --verbose
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ coverage
.env
.env.*
!.env.example
test-results
playwright-report
src-tauri/target
67 changes: 67 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Contributing to CoderKeys

Thank you for helping make CoderKeys better! This project is local-first, content-driven, and designed for community contributions.

## Quick start

```bash
git clone https://github.com/iagommendes/coderkeys.git
cd coderkeys
pnpm install
pnpm dev
```

## What you can contribute

| Area | Where to work | Guide |
|------|---------------|-------|
| **Lessons & tracks** | `content/` | [CONTRIBUTING-CONTENT.md](content/CONTRIBUTING-CONTENT.md) |
| **UI translations** | `apps/web/src/i18n/locales/` | [docs/ADDING-LOCALE.md](docs/ADDING-LOCALE.md) |
| **Color themes** | `apps/web/src/themes/` | [docs/ADDING-THEME.md](docs/ADDING-THEME.md) |
| **Typing engine** | `packages/engine/` | Add tests in `packages/engine/tests/` |
| **Web app** | `apps/web/` | Follow existing React + Tailwind patterns |

## Development workflow

1. Fork the repository and create a branch from `main`.
2. Make focused changes with clear commit messages.
3. Run checks locally before opening a PR:

```bash
pnpm typecheck
pnpm test
pnpm validate-content
pnpm check-i18n
pnpm build
```

4. Open a pull request using the PR template checklist.

## Project structure

```
apps/web/ React SPA (Vite)
packages/engine/ Typing engine (framework-agnostic)
packages/schemas/ Zod schemas shared across app and CI
content/ Lesson JSON files (contributor-friendly)
src-tauri/ Desktop wrapper (Tauri 2)
```

## Code style

- TypeScript strict mode — no `any` without justification
- Match existing naming and file layout
- Keep the engine free of React dependencies
- Prefer small, reviewable PRs

## Reporting issues

Use the GitHub issue forms:

- **New lesson** — propose a lesson idea
- **New locale** — request or offer a UI/content language
- **Bug report** — something broken in the app

## License

By contributing, you agree that your contributions will be licensed under the project's MIT License. Lesson content may use CC0 where noted in `content/CONTRIBUTING-CONTENT.md`.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ Open-source, local-first typing tutor tailored for **programmers** and **technic

## Features

- **Skill-based tracks** — Programmers (code syntax, symbols) and Technical Writers (requirements, documentation, translation)
- **Bilingual** — Interface and lessons in `en-US` and `pt-BR`
- **Skill-based tracks** — Programmers, Technical Writers, DevOps, Data Science, and Legal Translators
- **Multilingual** — UI in `en-US`, `pt-BR`, and `es-ES`; lessons in `en-US` and `pt-BR` (60+ lessons)
- **Custom themes** — Built-in dark, light, and Dracula color palettes
- **Desktop app** — Optional Tauri 2 wrapper for Linux, macOS, and Windows
- **Progress dashboard** — WPM charts, error heatmap, lesson suggestions
- **Translation mode** — Practice bilingual technical writing
- **100% local** — No backend, no cloud costs; progress saved in IndexedDB
Expand All @@ -31,8 +33,13 @@ pnpm preview # Preview production build locally
pnpm test # Run all tests
pnpm validate-content # Validate lesson JSON files
pnpm check-i18n # Verify translation key parity
pnpm test:e2e # Playwright end-to-end tests
pnpm tauri:dev # Desktop app (dev)
pnpm tauri:build # Desktop app (release)
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for contributor guidelines.

## Project Structure

```
Expand All @@ -41,6 +48,7 @@ coderkeys/
├── packages/engine/ # Typing engine (WPM, accuracy) — framework-agnostic
├── packages/schemas/ # Zod schemas for lessons and progress
├── content/ # Lesson content (contributors edit here)
├── src-tauri/ # Tauri 2 desktop wrapper
└── docs/ # Architecture and planning docs
```

Expand All @@ -51,7 +59,7 @@ coderkeys/
3. Run `pnpm validate-content`
4. Open a Pull Request

See [docs/PLANEJAMENTO-ARQUITETURA.md](docs/PLANEJAMENTO-ARQUITETURA.md) for the full architecture plan.
See [CONTRIBUTING.md](CONTRIBUTING.md) and [content/CONTRIBUTING-CONTENT.md](content/CONTRIBUTING-CONTENT.md).

## License

Expand Down
Loading
Loading