Commit graph

1778 commits

Author SHA1 Message Date
Siri-Ray
50d3ed0fd3
fix: enforce question form checkbox selection limits (#81) 2026-04-29 21:59:09 +08:00
Caprika
cf9b1c846a
Fix assistant agent labels (#70) 2026-04-29 21:34:05 +08:00
Tom Huang
4db0483721
chore: migrate frontend toolchain from Vite to Next.js 16 App Router (#66)
* 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>
2026-04-29 21:33:21 +08:00
ONEGAYI
536c077a04
fix(daemon): mitigate Windows ENAMETOOLONG and fix daemon crash on cleanup (#75)
* fix(daemon): mitigate Windows ENAMETOOLONG and fix daemon crash on temp-file cleanup

On Windows, child_process.spawn caps the command line at ~8,191 chars
(shell:true for .cmd/.bat npm shims via cmd.exe) and ~32,767 chars
(direct CreateProcess for .exe). When using Claude Code or Copilot CLI
(agents without promptViaStdin), the composed prompt (system prompt +
design system + skill body + user message) can exceed these limits,
causing spawn ENAMETOOLONG.

Mitigation: when the prompt exceeds the threshold, write it to a temp
file `.od-prompt.md` inside the project directory and pass a short
bootstrap message telling the agent to Read the file before responding.

- shell:true threshold: 4,000 chars (accounts for cmd.exe escaping overhead)
- Direct exe threshold: 30,000 chars
- Diagnostic logging only on Windows
- Temp file auto-cleaned on spawn error or child process exit

The temp-file cleanup used `fs.unlink(path).catch(() => {})`, but the
top-level `fs` module's unlink is callback-style and returns undefined,
not a Promise. Calling .catch() on undefined throws
ERR_INVALID_ARG_TYPE and crashes the daemon process.

Fixed with callback form `fs.unlink(path, () => {})` and extracted into
an idempotent `cleanPromptFile()` function to prevent double-delete when
both the spawn catch block and the child close handler fire.

- Eliminated duplicate `resolveAgentBin()` call within the same request
- Extracted constants: CMD_BAT_RE, PROMPT_TEMP_FILE, promptFileBootstrap()
- Reused resolvedBin variable instead of a second resolveAgentBin call

Close #52, Close #72

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(daemon): address PR review feedback on ENAMETOOLONG mitigation

- Use per-request unique temp filenames (timestamp + random suffix) to
  prevent race conditions when concurrent requests target the same project
- Normalize backslashes to forward slashes in the bootstrap message path
  for Windows compatibility with agents that shell out to POSIX tools
- Clean up temp prompt file on the missing-binary early-return path
- Raise shell:true threshold from 4000 to 6500 chars (cmd.exe escaping
  overhead is ~1.1-1.3x, not 2x, so the old value was overly conservative)
- Log only the basename of the resolved agent binary to avoid leaking
  user home-directory paths in diagnostic output
- Add comment documenting the idempotency guard ordering in
  cleanPromptFile (flag set synchronously before async fs.unlink)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-29 21:29:46 +08:00
Túlio Magnus
061df76f06
add pt-BR UI locale (#79) 2026-04-29 21:18:35 +08:00
Caprika
27e7e04e49
fix(chat): surface unfinished todo runs (#76) 2026-04-29 21:15:35 +08:00
nettee
f24bb669a7
feat: Add Hermes and Kimi runtime adapters (#71) 2026-04-29 20:53:44 +08:00
Aresdgi
6de39f065e
feat: add artifact platform foundation (#68)
* feat: add artifact manifest foundation

* feat: introduce artifact renderer registry

* fix: use unique artifact manifest sidecar names

* fix(artifacts): validate manifest payloads
2026-04-29 19:59:36 +08:00
Caprika
ea3e1c98bb
Fix document previews for uploaded files (#63)
* feat(files): preview uploaded documents

* fix(files): harden document preview
2026-04-29 19:18:08 +08:00
KNIGHTABDO
623444fe48
fix: deliver prompt via stdin for non-Claude agents to avoid spawn ENAMETOOLONG on Windows (#15)
The composed prompt (system instructions + skill body + cwd hint + file
listing + user message) can easily exceed Windows' CreateProcess limit of
~32 KB when passed as a CLI argument via -p <string>.  This causes
spawn ENAMETOOLONG whenever Gemini CLI (or Codex, OpenCode, Cursor
Agent, Qwen) is selected on Windows — even for short user messages,
because the skill / design-system system prompt is folded in.

Fix: add promptViaStdin: true to every plain-text agent definition.
The daemon's /api/chat handler checks this flag, opens stdin as a pipe,
writes the composed prompt to it and closes the stream.  Claude Code is
unaffected — it still uses the -p argv path and a separate stream-json
parser.

docs/agent-adapters.md: update §5.5 Gemini CLI to document the stdin
delivery strategy, and update the Windows open-question note to reflect
the fix.

Co-authored-by: KNIGHTABDO <abdessamad.aabida-etu@etu.univh2c.ma>
Co-authored-by: pftom <1043269994@qq.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: lefarcen <20859779+lefarcen@users.noreply.github.com>
2026-04-29 17:10:20 +08:00
Siri-Ray
6625674925
feat(import): support Claude Design zip imports (#46)
* feat(import): support Claude Design zip imports

* fix(import): address zip import review feedback

* fix(ui): align new project button icons
2026-04-29 17:09:15 +08:00
Aresdgi
2d3257fd7c
fix(design-files): support multi-file uploads (#31)
* fix(design-files): support multi-file uploads

* fix(design-files): report upload failures
2026-04-29 17:02:55 +08:00
0xKermini
10242d44ae
fix(daemon): support Claude Code CLI <1.0.86 (closes #33) (#34)
Two coupled bugs surfaced when the daemon resolved an older `claude`
binary on PATH:

1. Spawn crashed with "unknown option '--include-partial-messages'"
   because that flag landed in 1.0.86 and we passed it unconditionally.
2. Even after dropping the flag, the assistant bubble rendered empty —
   the stream parser only extracted text from `stream_event` deltas
   (only emitted under --include-partial-messages). Without those
   events, the full text in the `assistant` wrapper went unread.

Fix:
- Probe `claude --help` once during agent detection and cache which
  flags the installed CLI advertises (`agentCapabilities` map).
- `buildArgs` reads the cache and only emits `--include-partial-messages`
  / `--add-dir` when supported; safe baseline when probing fails.
- Warm the cache on server startup (`detectAgents()`) so the first
  /api/chat doesn't race ahead of the frontend's /api/agents call.
- Parse text (and thinking) blocks out of the `assistant` wrapper as a
  fallback, deduped via a per-message-id `textStreamed` set so newer
  builds streaming deltas never double-emit.

Co-authored-by: lukebaze <lukebaze@users.noreply.github.com>
Co-authored-by: lefarcen <20859779+lefarcen@users.noreply.github.com>
2026-04-29 17:00:45 +08:00
lakatos
9858f496fd
feat(agents): add GitHub Copilot CLI as a code-agent option (#28)
* feat(agents): add GitHub Copilot CLI as a code-agent option

Wire `copilot -p "..." --allow-all-tools` into AGENT_DEFS so the daemon
can spawn it alongside the other CLIs. `--allow-all-tools` is required
in non-interactive mode (same tradeoff as Claude's `-p` and Codex's
`exec`). Add a matching GitHub-dark icon with the Copilot two-eye mark.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(copilot-stream): treat result.success as completed when exitCode missing

Strict `obj.exitCode === 0 ? 'completed' : 'error'` mis-flags turns
where Copilot emits a `result` event with `success: true` but no numeric
exitCode. Switch to `obj.success === true || obj.exitCode === 0`. The
asymmetry argument that applies to other defensive ideas in this file
(raw fallback, stringifyResult cap) doesn't apply here — Claude's
`result` event uses a string `stop_reason`, not exitCode, so this is a
Copilot-specific schema-variance fix rather than a one-sided hardening.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs(agent-adapters): list Copilot CLI auth paths in §5.7

Adds a one-line note: detection assumes Copilot is already
authenticated, via either `copilot login` (subcommand, OAuth device
flow) or the interactive `/login` slash command inside `copilot` with
no args. Surfaces the assumption so anyone hitting an undetected /
unversioned Copilot install can trace it back.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 16:54:47 +08:00
Lin
9db6793029
feat(design-systems): add xiaohongshu (#24)
- Adds design-systems/xiaohongshu/DESIGN.md. Lands under Media & Consumer.
- Color, typography, layout, component, and dark-mode tokens sampled
  from production CSS at https://www.xiaohongshu.com/explore — the
  inline :root,.force-light and :root[dark],.force-dark blocks.
- Brand primary captured as two values: #FF2442 (the --primary token)
  and #FF2E4D (hard-coded on .reds-button-new.primary and .active-bar).
  Both ship in the live UI.
- Danger / error reuses --primary; no independent error token in source.
- Bookmark / collect star (#FDBC5F) sampled from the inline
  <symbol id="collected"> SVG path fill. Digits use the custom RED
  Number family (Regular / Medium / Bold).
- Narrative copy in English per CONTRIBUTING.md; real product strings
  (brand name, slogan, font name, follow-button labels, profile tab
  labels) kept verbatim with English glosses, mirroring
  pinterest/DESIGN.md preserving its Japanese font fallback names.
- Upstream VoltAgent/awesome-design-md does not currently include any
  Chinese-internet brand, so this lands directly in the OD bundled set
  rather than going to upstream first.
2026-04-29 16:54:42 +08:00
Tom Huang
da3d0d6627
fix: spawn agents via resolved absolute path on Windows (closes #10) (#13)
* fix: spawn agents via resolved absolute path on Windows (#10)

Detection in `/api/agents` resolves each agent's full executable path,
but `/api/chat` was spawning the bare `def.bin` ("claude"). On Windows
the child process's PATH often doesn't include the user's npm-global
shim directory, so spawn() failed with ENOENT despite the picker
showing the agent as available.

Use the resolved path at spawn time, and pass `shell: true` when the
resolved bin is a `.cmd`/`.bat` shim so Node ≥21 doesn't refuse to
execute it (CVE-2024-27980).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix: address PR #13 review — friendlier ENOENT, document shell:true caveats

- When `resolveAgentBin` returns null we now emit a friendly SSE `error`
  pointing at /api/agents and end the stream, instead of silently falling
  back to spawn(def.bin) — which would re-introduce the exact issue #10
  symptom this PR is meant to prevent.
- Strengthen the comment around `shell: true` on Windows: call out that
  the only thing keeping user-controlled prompt text safe today is Node's
  CVE-2024-27980 escaper, that the proper fix is to route the composed
  prompt through child stdin (not a new `-p $prompt`-style flag), and
  that cmd.exe's ~8191-char command-line cap reintroduces an
  ENAMETOOLONG-class failure for long prompts under shell:true.
- Document why the `.cmd`/`.bat` regex is the right gate: those are the
  only PATHEXT extensions that strictly need cmd.exe; `.exe`/`.com`
  launch directly and `.ps1`/`.vbs` would need a different host that
  shell:true (=cmd.exe) wouldn't help with.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 16:52:05 +08:00
lakatos
6cac039045
fix(guizang-ppt): sync host slide counter on transform-paginated decks (#19)
* fix(guizang-ppt): sync host slide counter on transform-paginated decks

go() previously only mutated #deck.style.transform on the parent track,
leaving .slide attributes untouched — so the iframe-host bridge in
src/runtime/srcdoc.ts couldn't detect which slide was active and the
host counter froze at 1/N. Toggle .active on the current .slide so
findActiveByClass returns the right index and the existing
MutationObserver fires a re-report.

* docs(guizang-ppt): mark .slide.active toggle as load-bearing for OD host counter
2026-04-29 16:52:00 +08:00
JoKer049
d155f2439d
fix(daemon): non-interactive permissions for agent CLIs in web UI (#26)
* fix(daemon): non-interactive permissions for agent CLIs in web UI

Claude Code and other CLIs prompt for tool approval; OD has no terminal
in the browser, so prompts stall the stream. Align spawn args with cwd
sandboxing: Claude bypassPermissions, Codex --full-auto, Gemini/Qwen
--yolo, Cursor --force.

Fixes https://github.com/nexu-io/open-design/issues/25

* fix(daemon): pass --force before -p for cursor-agent

---------

Co-authored-by: zhengyuanqing.zyq <zhengyuanqing.zyq@alibaba-inc.com>
2026-04-29 16:36:09 +08:00
PerishFire
3447af23f4
chore: add release beta workflow placeholder (#36) 2026-04-29 16:00:24 +08:00
Marc Chan
a6a2133527
fix: pin supported install toolchain (#35) 2026-04-29 15:40:25 +08:00
Tom Huang
1dbfbdcf5e
feat: per-CLI model picker for local agents (#14)
* feat: per-CLI model picker for local agents (closes #8)

Each agent CLI declares its selectable models (and reasoning effort, for
Codex) on the daemon side; the frontend renders a model dropdown in the
avatar menu and the Settings dialog scoped to the currently picked CLI,
persists the choice per-agent in the AppConfig, and threads it through
/api/chat to the spawn argv. "Default" leaves the flag off so the CLI's
own config wins.

* feat(models): fetch live model lists from CLIs, allow custom ids

Each agent definition now declares an optional `listModels` spec; the
daemon runs the CLI's own list-models command (e.g. `opencode models`,
`cursor-agent models`) during agent detection and uses the result as
the dropdown options. Hardcoded entries shrink to a `fallbackModels`
hint that only kicks in when the CLI has no listing command (Claude,
Codex, Gemini, Qwen) or when the listing fails (e.g. unauth'd
cursor-agent).

UI groups `provider/model` ids by provider via <optgroup> so opencode's
~175 live models stay navigable, and the Settings dialog gains a
"Custom…" entry that opens a free-text input for any model id the
listing didn't surface yet. Daemon validates picks against the live
cache + fallback, with a permissive sanitizer for custom ids.
2026-04-29 14:35:58 +08:00
Tom Huang
94941f59a9
feat(dev): auto-switch ports on dev:all when defaults are busy (#9)
* 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.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.

* Enhance README and add star promotion assets

- Added a "Star us" section in both English and Chinese README files to encourage users to star the project on GitHub.
- Included a new image asset for the star promotion.
- Introduced a new HTML file for a dedicated star promotion page.
- Updated .gitignore to exclude new cursor-related files.

* feat(dev): auto-switch ports on dev:all when defaults are busy

Adds a small launcher (scripts/dev-all.mjs) that probes free ports
for the daemon (OD_PORT, default 7456) and Vite (VITE_PORT, default
5173) before invoking concurrently, so a stray process holding
either port no longer breaks the boot. The resolved ports are
exported into the child env; vite.config.ts now reads VITE_PORT to
keep its dev server and /api proxy aligned with the daemon's actual
port.

Made-with: Cursor
2026-04-28 22:25:45 +08:00
Tom Huang
d243b37d74
fix: allow Claude Code to read skill seeds and design-system specs (#6) (#7)
* Allow Claude Code to read skill seeds and design-system specs (#6)

The skill body's preamble points the agent at absolute paths like
`<repo>/skills/guizang-ppt/assets/template.html`, but the agent's cwd
is `.od/projects/<id>/`. Without an explicit allowlist Claude Code
blocks Read on those paths and the user sees a permission error
mid-conversation.

Pass `SKILLS_DIR` and `DESIGN_SYSTEMS_DIR` through `buildArgs` and emit
them as `--add-dir` for Claude so the seed template, references, and
design-system DESIGN.md are all readable. Other agents ignore the
extra dirs (no equivalent flag).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* docs: add verification screenshot for issue #6 fix

Captures the agent successfully Read-ing skills/guizang-ppt/ side files
through the new --add-dir allowlist, confirming the permission error
from issue #6 is gone.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 22:25:32 +08:00
Tom Huang
1c942e6cb7
Feat/support star us (#5)
* 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.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.

* Enhance README and add star promotion assets

- Added a "Star us" section in both English and Chinese README files to encourage users to star the project on GitHub.
- Included a new image asset for the star promotion.
- Introduced a new HTML file for a dedicated star promotion page.
- Updated .gitignore to exclude new cursor-related files.
2026-04-28 21:00:33 +08:00
lakatos
d1c3230642
fix: welcome dialog Save overwriting user's agent pick (#4)
The Save button fired both onSave and onClose. onClose's closed-over
`config` still held the bootstrap default (agentId: 'claude'), so it
re-ran setConfig with the stale value right after onSave wrote the
user's choice — leaving the user with Claude Code even when they had
clicked Codex on first run.

Split the responsibilities: Save now owns close (handleConfigSave
calls setSettingsOpen(false)); onClose stays scoped to dismiss flows
(Skip / backdrop) where the stale-config write is harmless.
2026-04-28 20:41:27 +08:00
Tom Huang
bc2198103a
Feat/optimize naming (#2)
* 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.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.

* Update README and documentation for deck framework directives

- Clarified DECK_FRAMEWORK_DIRECTIVE description in both English and Chinese README files to specify conditions for deck kind without a skill seed.
- Added detailed workflow instructions in deck-framework.ts to emphasize the importance of copying the framework before adding content.
- Enhanced discovery.ts to reinforce the framework-first approach for deck projects.
- Updated system.ts to ensure proper handling of deck projects with and without bound skills, preventing re-authorship of scaling and navigation logic.
2026-04-28 16:28:19 +08:00
Tom Huang
6f6bf31dd2
Refactor project name from "Open Claude Design" to "Open Design" (#1)
* 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.
2026-04-28 16:03:35 +08:00
pftom
a98096a042 Add initial project structure with essential files
- Created .gitignore to exclude build artifacts and dependencies.
- Added index.html as the main entry point for the application.
- Included LICENSE file with Apache 2.0 terms.
- Initialized package.json and package-lock.json for project dependencies.
- Added pnpm-lock.yaml for package management.
- Created QUICKSTART.md for setup instructions.
- Added README.md and README.zh-CN.md for project documentation in English and Chinese.
2026-04-28 12:25:59 +08:00