Adds a public set of rules for the External Maintainer role: who qualifies,
how nominations work, what permissions Maintainers gain, what's expected
of them, and how step-down works.
The Core Team's individual roster is intentionally not enumerated. What's
public is the rules everyone plays by.
- New file: MAINTAINERS.md (English authoritative version) + 5 locale variants
matching the existing CONTRIBUTING.md i18n surface (de, fr, ja-JP, pt-BR,
zh-CN). Non-EN/non-zh-CN variants are machine-translated drafts marked at
the top — native-speaker review is welcome via follow-up PRs.
- CONTRIBUTING.md (and its 5 locale variants): adds a short
Becoming a Maintainer section that points at MAINTAINERS.md, so the
rules live in one place and translation drift is bounded.
Decisions not in this PR (intentional):
- No internal Core Team roster.
- No internal observability dashboards.
- No nomination PR / public voting flow (Core-Team-consensus-driven for now;
to be revisited once External Maintainers exceed 5).
Co-authored-by: Joey Li <lijinwei@open-design.ai>
- Add QUICKSTART.zh-TW.md (Traditional Chinese) based on the latest
QUICKSTART.zh-CN.md, with regional terminology for zh-TW locale.
- Update the language nav in all 6 existing QUICKSTART translations
to include the 繁體中文 entry.
- Fix CONTRIBUTING.zh-CN.md: point QUICKSTART references to the
Chinese translation (QUICKSTART.zh-CN.md) instead of the English
original, closing the follow-up promised in PR #578.
* chore: enforce test directory conventions
Move package, app, and tool tests out of src and add guard enforcement so source directories stay source-only.
* ci: use guard and package-scoped tests
Run the new repository guard in CI and keep test execution aligned with package-scoped commands after removing root aliases.
* ci: align stable release guard check
Use the new repository guard in stable release verification after replacing the residual-JS-only script.
* chore: tighten test layout enforcement
Enforce sibling tests directories, typecheck moved test suites with dedicated configs, and refresh remaining guidance that pointed at src-based tests.
* chore: clarify no-emit test tsconfigs
Explicitly disable declaration-only emit in test tsconfigs so review tooling sees they are no-emit typecheck configs.
* docs: add Brazilian Portuguese (pt-BR) translations
Translate README, CONTRIBUTING, QUICKSTART, and the e2e/cases,
e2e/reports, skills/html-ppt, skills/guizang-ppt READMEs into pt-BR.
Add the pt-BR entry to the language switcher in every existing locale
variant (en, de, fr, ko, ja-JP, ru, uk, zh-CN, zh-TW for README; en,
de, fr, ja-JP, zh-CN for CONTRIBUTING; en, de, fr, ja-JP for
QUICKSTART) so readers in any language can jump to the Portuguese
version. Code blocks, file paths, identifiers, license attribution
links and brand names are kept verbatim with the source.
* docs(pt-BR): use repo-relative links in e2e READMEs
Replace author-local absolute paths (/Users/mac/...) with repo-relative links so the translated docs navigate correctly on GitHub and other checkouts.
* docs(pt-BR): fix README badge anchor and skill reference link
- Update Agents badge href to the Portuguese fragment (#agentes-de-código-suportados) so the badge jumps to the translated heading.
- Restore the [`SKILL.md`][skill] reference-link syntax in the comparison table; the opening bracket was lost in translation, breaking the row.
* fix(web,daemon): make max_tokens configurable (closes#29)
BYOK users on custom Anthropic-compatible providers (e.g. Xiaomi MiMo)
hit the hardcoded 8192 cap and saw artifacts truncated mid-stream.
- AppConfig.maxTokens with Settings input (EN/CN + 8 other locales)
- ProxyStreamRequest.maxTokens contract field
- anthropic, anthropic-compatible, and openai-compatible providers all
forward cfg.maxTokens
- /api/proxy/anthropic/stream and /api/proxy/stream payloads honor it,
defaulting to 8192 when unset so prior clients are unaffected
Original sketch by @mashu in #78 (50a9d14); rebased to the apps/web
layout and extended to the proxy paths actually used when baseUrl is
set, which is where #29's user actually traffics.
* feat(web): per-model max_tokens defaults
Adds a hand-maintained MODEL_MAX_TOKENS table (Claude 4.5 line → 64k,
mimo-v2.5-pro → 32k) and an effectiveMaxTokens helper layered over the
override field added in 6a3ae5f, so #29's user — and others on supported
models — don't have to discover Settings to avoid mid-stream truncation.
- apps/web/src/state/maxTokens.ts: lookup + helpers
- providers/{anthropic,anthropic-compatible,openai-compatible}.ts:
forward effectiveMaxTokens(cfg) instead of cfg.maxTokens ?? 8192
- SettingsDialog: input becomes an optional override (blank = default,
shown as placeholder)
- 10 locale hint strings updated to the new semantics
* feat(web): vendor LiteLLM model metadata for max_tokens defaults
Replaces the 4-entry hand-rolled MODEL_MAX_TOKENS map from 544e67e with
a vendored slice of BerriAI/litellm's model_prices_and_context_window
JSON (1970 chat models, ~97KB raw / ~25KB gzip). Future model launches
land in maxTokens.ts via `pnpm sync-litellm-models` instead of manual
edits.
- scripts/sync-litellm-models.ts: fetches the upstream JSON, filters to
chat-mode entries, projects each entry to its max_output_tokens (or
max_tokens fallback), and writes a sorted, license-attributed JSON
- apps/web/src/state/litellm-models.json: generated artifact, committed
- apps/web/src/state/maxTokens.ts: lookup is now
OVERRIDES → LITELLM_MODELS → FALLBACK_MAX_TOKENS. The OVERRIDES table
shrinks to just `mimo-v2.5-pro` (LiteLLM only ships MiMo via
OpenRouter/Novita aliases, not the canonical id Xiaomi's API uses).
LiteLLM is MIT-licensed (BerriAI/litellm/blob/main/LICENSE); attribution
is preserved in both the script header and the generated JSON's
_license field.
* test(web,docs): cover maxTokens lookup + document sync workflow
- apps/web/src/state/maxTokens.test.ts: six vitest cases pinning the
three-tier lookup (override → LiteLLM → fallback) and the
effectiveMaxTokens user-override path. Guards against a future sync
silently dropping the Anthropic 4.5 entries we rely on.
- CONTRIBUTING.md / CONTRIBUTING.zh-CN.md: new "Updating model
max_tokens metadata" section pointing future maintainers at
scripts/sync-litellm-models.ts and explaining when OVERRIDES is
appropriate (it's the rare exception, not the default).
* fix(web): mark Max tokens label as optional in 10 locales
The Settings field is optional (blank means "use the per-model default")
but the label gave no visual cue, breaking the implicit pattern that
every other API-mode field (key/model/baseUrl) is required. Append
"(optional)" — using the locale's natural parenthetical convention
(Chinese full-width brackets, Japanese 任意, Russian опционально, etc.)
— so the field reads as discretionary at a glance.
* fix(web): validate maxTokens override against advertised UI bounds
Addresses Siri-Ray's review on commit 0d98185. The Settings input
declares min={1024}/max={200000}/step={1024}, but until now
effectiveMaxTokens trusted any defined cfg.maxTokens, so a stale or
hand-edited localStorage value (negative, zero, fractional, billions)
would pass straight to the Anthropic SDK on the direct path while the
daemon proxy quietly clamped it back to 8192 on the proxied path —
same config, divergent behavior depending on route.
- maxTokens.ts: add MIN_MAX_TOKENS / MAX_MAX_TOKENS exports and
isValidOverride helper. effectiveMaxTokens only honors the override
when it is a finite integer in [1024, 200000]; otherwise falls back
to modelMaxTokensDefault.
- SettingsDialog.tsx: input bounds now reference the same constants so
the UI promise can't drift from the runtime check.
- maxTokens.test.ts: six new cases pinning the rejection of negative,
zero, sub-MIN, super-MAX, non-integer (fractional / NaN / Infinity)
overrides plus the inclusive MIN/MAX boundaries.
The daemon proxy's existing `> 0` fallback stays as defense-in-depth.
* feat(dev): add desktop tools-dev control plane
* refactor(sidecar): split Open Design contracts
Move Open Design-specific sidecar protocol definitions into @open-design/contracts so sidecar and platform can remain descriptor-driven primitives.
* refactor(daemon): organize package sources
Keep daemon app code, tests, and sidecar entrypoints in separate package directories so each layer can be built and verified independently.
* chore(repo): streamline maintenance entrypoints
Centralize agent guidance by directory and reduce root command chains while preserving the existing build scope.
* docs: translate agent guidance to English
* fix(sidecar): tolerate stale IPC sockets
Remove stale Unix socket files only after confirming no listener is active, so tools-dev can restart after unclean shutdowns.
* Refactor project name from "Open Claude Design" to "Open Design"
- Updated project name in package.json, package-lock.json, and README files.
- Changed CLI commands and references from "ocd" to "od".
- Adjusted file structure references in documentation and code to reflect new naming conventions.
- Enhanced .gitignore to include new runtime data files.
- Updated metadata in LICENSE file to match new project name.
* chore: migrate frontend toolchain from Vite to Next.js 16 App Router
Replace the Vite SPA scaffold with Next.js 16 App Router while keeping
the existing daemon as the API/SSE/sqlite backend. The whole client
tree now mounts under a single optional catch-all route
(app/[[...slug]]) loaded with ssr:false; static export emits one shell
HTML the daemon serves as the SPA fallback for deep links. Dev uses
next.config rewrites to proxy /api, /artifacts, /frames to the daemon,
matching the previous Vite setup.
Made-with: Cursor
* fix: address Next migration review feedback
* fix: serve static export in preview script
---------
Co-authored-by: mrcfps <mrc@powerformer.com>
* Refactor project name from "Open Claude Design" to "Open Design"
- Updated project name in package.json, package-lock.json, and README files.
- Changed CLI commands and references from "ocd" to "od".
- Adjusted file structure references in documentation and code to reflect new naming conventions.
- Enhanced .gitignore to include new runtime data files.
- Updated metadata in LICENSE file to match new project name.
* Add contributing guidelines in English and Chinese
- Introduced CONTRIBUTING.md and CONTRIBUTING.zh-CN.md to provide clear instructions for contributors.
- Outlined contribution types, local setup instructions, and merging criteria for skills and design systems.
- Enhanced README files to reference the new contributing guidelines.