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
2 changes: 2 additions & 0 deletions .opencode/agent/code-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Review all code changes for correctness, standards compliance, and quality. You
- Check for deprecated API usage.
- Verify error handling follows project conventions.
- Ensure code follows the project's structure and naming conventions.
- Flag any hardcoded text strings in `.astro` templates — all user-facing strings must use the i18n system (`t()`). This is a blocking issue.
- Verify new translation keys are properly registered in `src/i18n/ui.ts`.

## Output Format

Expand Down
5 changes: 5 additions & 0 deletions .opencode/agent/frontend-engineer.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,15 @@ Implement the user-facing parts of the application — interfaces, presentation
- Build output formatting and display logic.
- Handle user input validation and feedback.
- Ensure consistent user experience across the application.
- Use the project's i18n system (`useTranslations`, `t()`) for ALL user-facing text.
- Place new translation keys in `src/i18n/ui.ts` under the appropriate page namespace.
- Never hardcode Portuguese or any language strings in templates.

## Guidelines

- Study existing code patterns before writing new code.
- Follow the project's established conventions and style.
- Keep interface logic thin — delegate business logic to internal modules.
- Load the `astro-i18n` skill before writing any `.astro` file.
- Before writing a new page, first check `src/i18n/ui.ts` for existing keys that match the content you need.
- Validate and verify your changes build and pass tests before reporting done.
16 changes: 15 additions & 1 deletion .opencode/learnings/registry.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ All captured learnings from the AI Diamond Chain are registered here.

```markdown
## [Date] - [Learning Title]

- **Type:** skill/agent/workflow/reference
- **Source:** Which diamond/event produced this
- **Summary:** 1-2 sentence description
Expand All @@ -25,6 +26,7 @@ All captured learnings from the AI Diamond Chain are registered here.
---

## 2026-04-17 - Continuous Learning System

- **Type:** skill
- **Source:** User request to create learning rules
- **Summary:** Created continuous-learning skill and supporting docs to ensure all learnings are captured, condensed for reuse, and documented for long-term reference
Expand All @@ -34,6 +36,7 @@ All captured learnings from the AI Diamond Chain are registered here.
---

## 2026-04-17 - Tmux Automation Skill

- **Type:** skill
- **Source:** User request for tmux skill for detached session control
- **Summary:** Created tmux-automation skill with commands for creating detached sessions, sending keys programmatically, capturing output, and session management
Expand All @@ -43,8 +46,19 @@ All captured learnings from the AI Diamond Chain are registered here.
---

## 2026-04-18 - DaisyUI v5 Custom Theme Configuration

- **Type:** skill
- **Source:** Implementation Diamond - Custom theme creation for PodCodar brand
- **Summary:** Learned DaisyUI v5's new `@plugin "daisyui/theme"` syntax with OKLCH color format, created light/dark theme pair with PodCodar brand colors (tech blues + warm amber accents), disabled default themes for clean implementation
- **Location:** `.opencode/skills/daisyui-v5-themes/SKILL.md`, `src/styles/global.css`
- **Confidence:** 🟢 High
- **Confidence:** 🟢 High

---

## 2026-04-26 - i18n Text Convention: No Hardcoded Strings

- **Type:** skill/agent/workflow
- **Source:** Refactoring transparency layout to /about, /join-us, /contact — discovered massive duplication of hardcoded strings across pages
- **Summary:** Established mandatory convention: ALL user-visible text in `.astro` templates must use the i18n system (`t()`). Updated `astro-i18n` skill with text convention rule, updated `frontend-engineer` and `code-reviewer` agents to enforce it, and documented in `AGENTS.md`. Data-driven content from `src/data/*.ts` files (member names, metric values, etc.) is exempted.
- **Location:** `.opencode/skills/astro-i18n/SKILL.md`, `.opencode/agent/frontend-engineer.md`, `.opencode/agent/code-reviewer.md`, `AGENTS.md`
- **Confidence:** 🟢 High
120 changes: 98 additions & 22 deletions .opencode/skills/astro-i18n/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ compatibility: opencode
## Quick Start

### 1. Configure astro.config.mjs

```js
i18n: {
locales: ['pt-br', 'en'],
Expand All @@ -23,12 +24,14 @@ i18n: {
```

### 2. Create Translation Files

```
src/i18n/ui.ts # Translation strings
src/i18n/utils.ts # Helper functions
```

### 3. Organize Pages

```
src/pages/
├── index.astro # default locale (pt-br)
Expand All @@ -46,53 +49,57 @@ src/pages/
## Core Concepts

### Locale Detection Priority

1. **Cookie** (user selected) - highest priority
2. **Browser Accept-Language header** - middleware (SSR required)
3. **Default locale** - fallback

### URL Structure

| prefixDefaultLocale | default locale URL | other locale URL |
|---------------------|-------------------|-----------------|
| false | `/` | `/en/` |
| true | `/pt-br/` | `/en/` |
| ------------------- | ------------------ | ---------------- |
| false | `/` | `/en/` |
| true | `/pt-br/` | `/en/` |

---

## File Reference

### src/i18n/ui.ts

```typescript
export const languages = {
en: 'English',
'pt-br': 'Português (Brasil)',
en: "English",
"pt-br": "Português (Brasil)",
} as const;

export const defaultLang = 'pt-br';
export const defaultLang = "pt-br";

export const ui = {
en: {
'nav.home': 'Home',
'nav.blog': 'Blog',
'nav.about': 'About',
'nav.contact': 'Contact',
'footer.copyright': 'All rights reserved.',
"nav.home": "Home",
"nav.blog": "Blog",
"nav.about": "About",
"nav.contact": "Contact",
"footer.copyright": "All rights reserved.",
},
'pt-br': {
'nav.home': 'Início',
'nav.blog': 'Blog',
'nav.about': 'Sobre',
'nav.contact': 'Contato',
'footer.copyright': 'Todos os direitos reservados.',
"pt-br": {
"nav.home": "Início",
"nav.blog": "Blog",
"nav.about": "Sobre",
"nav.contact": "Contato",
"footer.copyright": "Todos os direitos reservados.",
},
} as const;
```

### src/i18n/utils.ts

```typescript
import { ui, defaultLang } from './ui';
import { ui, defaultLang } from "./ui";

export function getLangFromUrl(url: URL): keyof typeof ui {
const segments = url.pathname.split('/').filter(Boolean);
const segments = url.pathname.split("/").filter(Boolean);
const firstSegment = segments[0];
if (firstSegment && firstSegment in ui) {
return firstSegment as keyof typeof ui;
Expand Down Expand Up @@ -146,6 +153,7 @@ const t = useTranslations(lang);
## Language Picker with Cookie Persistence

### src/components/LanguagePicker.astro

```astro
---
import { getRelativeLocaleUrl } from 'astro:i18n';
Expand Down Expand Up @@ -203,15 +211,76 @@ const currentPath = getPathWithoutLocale(pathname, currentLang);

---

## Text Convention (MANDATORY)

ALL user-visible text in `.astro` files MUST use the i18n system. Hardcoded
strings in templates are forbidden.

### Correct

```astro
---
import { getLangFromUrl, useTranslations } from '@/i18n/utils';
const lang = getLangFromUrl(Astro.url);
const t = useTranslations(lang);
---
<HeroSection title={t('about.hero.title')} eyebrow={t('about.hero.eyebrow')} />
<SectionHeader title={t('contact.methods.title')} subtitle={t('contact.methods.subtitle')} />
<p>{t('contributing.donations.body')}</p>
```

### Wrong

```astro
<HeroSection title="Sobre nós" eyebrow="PodCodar" />
<SectionHeader title="Canais de Comunicação" subtitle="Escolha o canal..." />
<p>Se quiser contribuir financeiramente...</p>
```

### Exception

Data-driven content from `src/data/*.ts` files (board member names, metric
values, channel names, project names) is iterable data, not display strings.
These may be used directly:

```astro
<!-- OK — iterated from marketing.ts data -->
{projects.map((project) => <h3>{project.name}</h3>)}

<!-- NOT OK — hardcoded section header -->
<h2>Projetos e repositórios</h2>
<!-- Should be: -->
<h2>{t('about.projects.title')}</h2>
```

### Adding New Keys

When adding a new key to `src/i18n/ui.ts`, follow the namespace pattern:

```
{page}.{section}.{field}
```

Examples:

- `about.hero.eyebrow` — About page, hero section, eyebrow badge
- `joinUs.steps.01.title` — Join Us page, steps section, step 1 title
- `contributing.volunteering.body` — Contributing page, volunteering section, body text

---

## Common Pitfalls

### 1. Hardcoded lang Attribute

**WRONG**:

```html
<html lang="en">
<html lang="en"></html>
```

**CORRECT**:

```astro
---
import { getLangFromUrl } from '../i18n/utils';
Expand All @@ -221,12 +290,15 @@ const lang = getLangFromUrl(Astro.url);
```

### 2. Static Links Without getRelativeLocaleUrl

**WRONG**:

```html
<a href="/about">
<a href="/about"></a>
```

**CORRECT**:

```astro
---
import { getRelativeLocaleUrl } from 'astro:i18n';
Expand All @@ -236,13 +308,16 @@ const lang = getLangFromUrl(Astro.url);
```

### 3. Wrong Default Locale

**WRONG** (default must be explicitly set):

```js
locales: ['en', 'pt-br'],
defaultLocale: 'en',
```

**CORRECT**:

```js
locales: ['pt-br', 'en'],
defaultLocale: 'pt-br',
Expand Down Expand Up @@ -278,6 +353,7 @@ defaultLocale: 'pt-br',
## When Server-Side Redirect is Needed

For server-side redirect based on browser language, add SSR adapter:

1. Install `@astrojs/node`
2. Set `output: 'server'`
3. Create `src/middleware.ts` for server-side detection
Expand Down Expand Up @@ -311,4 +387,4 @@ src/
│ └── LanguagePicker.astro
└── layouts/
└── BlogPost.astro
```
```
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,8 @@ This squad uses 9 specialized agents:
- **Configured in**: `astro.config.ts`
- **Skill available**: `astro-i18n` for adding English support
- Default locale does not use URL prefix (`prefixDefaultLocale: false`)
- **Convention**: ALL user-visible text in `.astro` templates must go through the i18n system (`t()`). Hardcoded strings are not allowed. See the `astro-i18n` skill for the full rule.
- **How**: Import `useTranslations` from `@/i18n/utils`, call `t('key')`. Add keys to `src/i18n/ui.ts` under the relevant page namespace (e.g., `about.hero.title`).

---

Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog

## Upcoming Release

- Consistent Layout across pages (#254)
- Mobile-Friendly navbar (#252)
Loading
Loading