Skip to content

Add objectstack-i18n skill for internationalization design guidance#1124

Merged
hotlong merged 1 commit intomainfrom
claude/create-skills-i18n
Apr 13, 2026
Merged

Add objectstack-i18n skill for internationalization design guidance#1124
hotlong merged 1 commit intomainfrom
claude/create-skills-i18n

Conversation

@Claude
Copy link
Copy Markdown
Contributor

@Claude Claude AI commented Apr 13, 2026

Created comprehensive skill documentation for internationalization (i18n) design in ObjectStack applications.

Changes

New Skill: skills/objectstack-i18n/

  • SKILL.md (696 lines) — Complete i18n design guide covering:

    • Translation configuration (defaultLocale, supportedLocales, fileOrganization strategies)
    • Object-first translation bundle structure (AppTranslationBundle, ObjectTranslationNode)
    • File organization patterns: bundled, per_locale, per_namespace
    • Coverage detection and diff analysis for missing/stale translations
    • AI-powered translation suggestions via II18nService.suggestTranslations()
    • Message interpolation formats (simple {variable} vs ICU MessageFormat)
    • Integration patterns with II18nService and I18nServicePlugin
    • Translation workflow best practices and common pitfalls
  • Reference schemas copied from packages/spec/src/:

    • system/translation.zod.ts — Translation bundle schemas
    • contracts/i18n-service.ts — Service interface contract
    • ui/i18n.zod.ts — UI-level i18n schemas

Updated Custom Instructions

  • Added objectstack-i18n to .github/copilot-instructions.md:
    • Skills directory listing
    • AI Skills Integration table with usage guidance

Example Usage

// Translation bundle structure (object-first convention)
const zh: AppTranslationBundle = {
  _meta: { locale: 'zh-CN', direction: 'ltr' },
  
  o: {
    account: {
      label: '客户',
      fields: {
        name: { label: '客户名称', help: '公司或组织的法定名称' },
        industry: { 
          label: '行业',
          options: { tech: '科技', finance: '金融' }
        }
      },
      _views: { all_accounts: { label: '全部客户' } }
    }
  },
  
  messages: { 'common.save': '保存' }
};

Aligns with Salesforce/Dynamics 365 object-first translation conventions where all translatable content for an object is grouped under a single namespace (o.{object_name}).

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectstack-play Ready Ready Preview, Comment Apr 13, 2026 2:37pm
spec Ready Ready Preview, Comment Apr 13, 2026 2:37pm

Request Review

@hotlong hotlong marked this pull request as ready for review April 13, 2026 14:37
Copilot AI review requested due to automatic review settings April 13, 2026 14:37
@hotlong hotlong merged commit 1dcc09e into main Apr 13, 2026
12 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new objectstack-i18n skill with comprehensive internationalization design guidance and bundles relevant spec references for AI consumption, plus updates the repo’s Copilot instructions to include the new skill.

Changes:

  • Added skills/objectstack-i18n/SKILL.md with i18n configuration, bundle structures, coverage/suggestions concepts, and workflow guidance.
  • Added skills/objectstack-i18n/references/** containing copied Zod schemas/contracts for i18n-related protocols.
  • Updated .github/copilot-instructions.md to list objectstack-i18n in the skills inventory and integration table.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
skills/objectstack-i18n/SKILL.md New i18n design skill documentation (config, bundle structure, coverage, workflows, integration).
skills/objectstack-i18n/references/system/translation.zod.ts Bundled reference copy of translation/i18n schemas for the skill.
skills/objectstack-i18n/references/contracts/i18n-service.ts Bundled reference copy of the II18nService contract for the skill.
skills/objectstack-i18n/references/ui/i18n.zod.ts Bundled reference copy of UI-level i18n schemas for the skill.
skills/objectstack-i18n/references/_index.md Index page describing included reference schemas and dependencies.
.github/copilot-instructions.md Adds the new skill to the skills list and “AI Skills Integration” table; updates sync date.

Comment on lines +403 to +409
Use `{variable}` placeholders:

```json
{
"messages": {
"welcome": "Welcome, {userName}!",
"pagination": "Showing {start} to {end} of {total} items"
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “Simple Format” interpolation syntax here uses {variable}, but the current built-in i18n implementations (e.g. createMemoryI18n in packages/core/src/fallbacks/memory-i18n.ts and FileI18nAdapter in packages/services/service-i18n/src/file-i18n-adapter.ts) interpolate {{variable}}. Update this section (and examples below) to match the actual {{paramName}} convention, or explicitly document the difference if {variable} is intended for a different implementation.

Suggested change
Use `{variable}` placeholders:
```json
{
"messages": {
"welcome": "Welcome, {userName}!",
"pagination": "Showing {start} to {end} of {total} items"
Use `{{paramName}}` placeholders:
```json
{
"messages": {
"welcome": "Welcome, {{userName}}!",
"pagination": "Showing {{start}} to {{end}} of {{total}} items"

Copilot uses AI. Check for mistakes.
Comment on lines +415 to +417
```typescript
i18n.t('messages.welcome', 'en', { userName: 'Alice' });
// "Welcome, Alice!"
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This usage example relies on the placeholder format described above; with the current runtime interpolation ({{paramName}}), the message template and/or this example call should be adjusted so that it matches what II18nService.t() actually replaces at runtime.

Copilot uses AI. Check for mistakes.
Comment on lines +77 to +79
| `defaultLocale` | `string` | `'en'` | Default BCP-47 locale code |
| `supportedLocales` | `string[]` | `['en']` | All supported locales |
| `fallbackLocale` | `string` | same as `defaultLocale` | Fallback when translation missing |
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This table lists defaults for defaultLocale and supportedLocales, but in the actual TranslationConfigSchema (packages/spec/src/system/translation.zod.ts) those fields are required whenever i18n config is provided (only fileOrganization, messageFormat, lazyLoad, cache have schema defaults). Consider marking these as required and only documenting defaults for fields that truly default in the schema/runtime.

Suggested change
| `defaultLocale` | `string` | `'en'` | Default BCP-47 locale code |
| `supportedLocales` | `string[]` | `['en']` | All supported locales |
| `fallbackLocale` | `string` | same as `defaultLocale` | Fallback when translation missing |
| `defaultLocale` | `string` | Required | Default BCP-47 locale code |
| `supportedLocales` | `string[]` | Required | All supported locales |
| `fallbackLocale` | `string?` | | Fallback when translation missing |

Copilot uses AI. Check for mistakes.
import { I18nServicePlugin } from '@objectstack/service-i18n';

const kernel = new ObjectKernel();
kernel.use(new I18nServicePlugin({
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ObjectKernel.use() is async (returns a Promise) in @objectstack/core; without await, plugin registration may race with kernel.bootstrap(). Update this snippet to await kernel.use(...) (or clarify if this is intentionally showing LiteKernel-style sync usage).

Suggested change
kernel.use(new I18nServicePlugin({
await kernel.use(new I18nServicePlugin({

Copilot uses AI. Check for mistakes.
Comment on lines +513 to +517
Use the CLI or API to extract all translatable keys from your metadata:

```bash
objectstack i18n extract --locale zh-CN --output i18n/zh-CN.json
```
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These CLI commands (objectstack i18n extract/suggest/coverage) don’t appear to exist in the current CLI command set (packages/cli/src/commands has no i18n command). Either update this workflow to reference the actual commands/API endpoints available today, or clearly label these as planned/proposed commands to avoid sending readers down a dead end.

Copilot uses AI. Check for mistakes.
Comment on lines +322 to +339
The `II18nService.getCoverage()` method compares a translation bundle against source metadata to detect:

1. **Missing** — Keys that exist in metadata but not in the translation bundle
2. **Redundant** — Keys in the bundle that have no matching metadata
3. **Stale** — Keys where the source metadata has changed since translation

```typescript
const coverage = i18nService.getCoverage('zh-CN', 'account');

console.log(coverage);
// {
// locale: 'zh-CN',
// objectName: 'account',
// totalKeys: 120,
// translatedKeys: 105,
// missingKeys: 12,
// redundantKeys: 3,
// staleKeys: 0,
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section treats II18nService.getCoverage() as a guaranteed capability, but the contract marks it optional and there is currently no implementation in the shipped i18n services (packages/services/service-i18n only implements t/getTranslations/loadTranslations/getLocales). Consider rephrasing as “if implemented” and advising callers to feature-detect (typeof i18nService.getCoverage === 'function') before calling.

Suggested change
The `II18nService.getCoverage()` method compares a translation bundle against source metadata to detect:
1. **Missing** — Keys that exist in metadata but not in the translation bundle
2. **Redundant** — Keys in the bundle that have no matching metadata
3. **Stale** — Keys where the source metadata has changed since translation
```typescript
const coverage = i18nService.getCoverage('zh-CN', 'account');
console.log(coverage);
// {
// locale: 'zh-CN',
// objectName: 'account',
// totalKeys: 120,
// translatedKeys: 105,
// missingKeys: 12,
// redundantKeys: 3,
// staleKeys: 0,
If implemented by the active `II18nService`, the optional `getCoverage()` method can compare a translation bundle against source metadata to detect:
1. **Missing** — Keys that exist in metadata but not in the translation bundle
2. **Redundant** — Keys in the bundle that have no matching metadata
3. **Stale** — Keys where the source metadata has changed since translation
Feature-detect `getCoverage()` before calling it:
```typescript
if (typeof i18nService.getCoverage === 'function') {
const coverage = i18nService.getCoverage('zh-CN', 'account');
console.log(coverage);
// {
// locale: 'zh-CN',
// objectName: 'account',
// totalKeys: 120,
// translatedKeys: 105,
// missingKeys: 12,
// redundantKeys: 3,
// staleKeys: 0,

Copilot uses AI. Check for mistakes.
Comment on lines 90 to 94
├── skills/ # 🤖 AI skill definitions (for Copilot/Cursor)
│ ├── objectstack-data/
│ ├── objectstack-api/
│ ├── objectstack-ui/
│ ├── objectstack-automation/
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The “Monorepo Structure” skills list is labeled as “Current State” and the header says it was synced on 2026-04-13, but it omits existing skill directories (e.g. skills/objectstack-kernel/, skills/objectstack-quickstart/, skills/objectstack-hooks/). Either include the full set of skills here or make it explicit that the list is partial (e.g. add an ellipsis).

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/xl

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants