mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
common-sphere
286
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
31c0bd159f |
fix(research): require canonical SHA on install, validate memory tags
- installHubEntry now requires entry.source.commitSha to match FULL_COMMIT_SHA_PATTERN (40 hex chars). The shorter prefix shape was a trust gap: an in-process caller could craft an entry whose commitSha matched the approval string by luck, pass the equality check, and trigger a re-fetch with ?ref=<short> that GitHub resolves through branch/tag names. - createMemory now validates input.tags as a bounded array of slug strings (max 16 entries, 64 bytes each, 512 bytes total) and rejects control characters and prompt-frame tokens, so a future memory route cannot bypass the 8KB content cap by smuggling instruction-like strings through tags that buildMemoryPrefix renders into the prompt JSON. - Added regression tests for both gates. Generated-By: looper 0.6.1 (runner=fixer, agent=claude-code) |
||
|
|
8ff084cf44 |
fix(research): thread server-owned token to installHubEntry re-fetch
`installHubEntry` re-fetches the manifest at the approved commit SHA before writing, but the call into `fetchManifestRawAtSha()` did not pass any token. `HubEntry.source` deliberately records `repo/path/commitSha` without a token (forwarding an entry must not exfiltrate credentials), so for a hub listed through `HubConfig.token` / `OD_HUB_TOKEN` the re-fetch hit the GitHub API anonymously and returned 404 — breaking the in-process install path documented as usable for entries from `listHubEntries()` against a private hub (PR #617 review, P1). `InstallOptions` now carries an optional server-owned `token`. The install path prefers `opts.token` and falls back to `OD_HUB_TOKEN` when the caller leaves it unset, mirroring the env-var contract `listHubEntries()` already honors. The token is intentionally kept out-of-band on the options object so a forwarded `HubEntry` still cannot carry credentials across a process boundary; callers that don't already hold a server-owned token should route through `installHubManifest`, which takes the token on the selector instead. Adds two regression cases to `apps/daemon/tests/research-skill-hub-install.test.ts`: - `threads opts.token through the re-fetch so private-hub entries install` — the mock returns 404 unless the bearer token matches, so the test fails if the install path forgets to thread the token. - `falls back to OD_HUB_TOKEN when opts.token is not supplied` — covers processes configured the same way as the listing call site. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
624820f192 |
fix(research): partition skill-hub cache, re-fetch on install, bound audit lines
Addresses four PR #617 review threads: - listHubEntries cache key now partitions on a per-process HMAC fingerprint of the bearer token (or the literal "public" sentinel for tokenless requests). This stops a tokened request that surfaces private hub manifests from being served back to a later tokenless request with the same (repo, ref, namespace), where `entry.raw` is prompt material. - installHubEntry no longer trusts caller-supplied `entry.raw`. After the SHA equality check it re-fetches the manifest from `/repos/.../<entry.source.path>?ref=<entry.source.commitSha>` and writes only the freshly fetched bytes; if those bytes drift from `entry.raw` the install is rejected. A new `installHubManifest` entry point takes a server-owned selector `{ namespace, name, repo, pinnedSha }` and is the recommended surface for any future `POST /api/skill-hub/install` route — HTTP bodies never carry manifest bytes through the writer. - The audit-log redaction pass now caps array length, object key count, and the final serialized JSONL line. Items past the per-container caps are replaced with a single truncation marker; lines past the byte cap collapse `detail` to a `__truncated` marker carrying the original size, so a pathological `detail` cannot block the daemon on synchronous JSON.stringify / appendFileSync. - The Skill Hub example in `docs/research/openwork-aionui-alaude- integration.md` now mirrors the safe install path the starter enforces: pinned-SHA listing, `installHubManifest` taking a selector + approval, re-fetch inside the install path, the quarantine/activation boundary, and SHA-pinned sibling-asset fetches. Adds `apps/daemon/tests/research-audit-log-bounds.test.ts` covering the new caps, and extends the install test with a re-fetch / drift case plus selector-based install coverage. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
31399fefed |
fix(research): resolve hub pinnedSha to canonical commit SHA via GitHub API
`COMMIT_SHA_PATTERN` was treating any 7–40 hex string as immutable provenance, but GitHub's `?ref=` parameter also accepts branch and tag names. A hub repo could create a mutable branch/tag named like a short SHA, pass the regex, fetch mutable-ref bytes, and then satisfy `installHubEntry` because `entry.source.commitSha` and `approval.pinnedSha` would both be the caller-supplied string (PR #617 review, P1). `listHubEntries` now resolves the caller-supplied SHA prefix through `GET /repos/{owner}/{repo}/commits/{input}` before any listing happens. The canonical 40-char `.sha` is required to share the input's lowercase hex prefix; otherwise GitHub resolved the ref through a branch/tag and we refuse to treat it as immutable provenance. The canonical full SHA is then used as the `?ref=` value and stamped on every `HubEntry.source.commitSha`, so `installHubEntry`'s exact-match equality compares 40-char canonical values on both sides. Adds `apps/daemon/tests/research-skill-hub-resolve.test.ts` with three cases: hex-shaped pinnedSha that resolves through a branch is rejected before any Contents API call; a real prefix that resolves to a sharing commit is accepted; and the listing/Contents API both use the canonical 40-char SHA, never the caller's raw 7-char input. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
8f66221e0b |
fix(research): tie skill-hub install bytes to the approved commit SHA
`installHubEntry` previously accepted any SHA-shaped `approval.pinnedSha` without verifying that the bytes in `entry.raw` came from that commit. Because `listHubEntries` fetched through the configured mutable branch ref and `HubEntry.source` carried no immutable provenance, a caller could list from `main`, pass any SHA-shaped string with `userApproved: true`, and still install unpinned branch content into active prompt directories. This change carries provenance end-to-end: - `HubConfig` accepts `pinnedSha` (or `OD_HUB_PINNED_SHA`); when set, `listHubEntries` / `readDirEntry` / `readFileEntry` route the GitHub Contents API through `?ref=<sha>` and stamp every returned `HubEntry.source.commitSha` with that SHA. - The list cache key now hashes the resolved ref (SHA or branch) so a pinned listing can never collide with a branch-tip listing. - `installHubEntry` now refuses any entry whose `source.commitSha` is missing (mutable-branch listing) or does not match `approval.pinnedSha` (case-insensitive exact equality, no prefix matching). The planning comment block is updated to reflect that the SHA-anchored install path is now enforced rather than future-tense. Adds `apps/daemon/tests/research-skill-hub-install.test.ts` covering: mutable-branch entry rejected, mismatched approval SHA rejected, matched SHA accepted, case-insensitive equality, short-prefix SHA rejected, untrusted `userApproved: false`, and malformed approval SHA. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
02cd4c61e7 |
fix(research): expand skill-hub mode list and parse block-scalar descriptions
Frontmatter validation in the research skill-hub starter now mirrors the shapes already used by `skills/*/SKILL.md`: - `ALLOWED_OD_MODES` adds `image`, `video`, `audio`, and `utility` so media and utility skills (e.g. `image-poster`, `video-shortform`, `audio-jingle`, `pptx-html-fidelity-audit`) are no longer rejected by a hub mirroring the catalog. - The minimal YAML parser now reads `description: |`, `description: |-`, `description: >`, and `description: >-` block scalars instead of storing the literal `|` / `>`. Continuation lines are joined with `\n` and right-trimmed, matching `apps/daemon/src/frontmatter.ts`. - Adds `apps/daemon/tests/research-skill-hub-frontmatter.test.ts` with fixture coverage against representative live skills for every currently-used `od.mode` value plus inline cases for `>` / `|-`. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
c706866068 |
fix(research): redact camelCase secrets, gate hub install, daemon-side browser MCP
- audit-log: redact camelCase secret keys (`accessToken`, `refreshToken`, `clientSecret`, `sessionId`, etc.) by inserting separators at case transitions before pattern test (PR #617 review, P2). - skill-hub: require explicit `InstallApproval { pinnedSha, userApproved }` on `installHubEntry` and document the trust boundary — manifest validation alone is not a trust step (PR #617 review, P1). - research doc: rewrite browser-use plan to remove the false "all agents are sandboxed" / "MCP tool consent already standard" premises; require daemon-owned MCP proxy with default-deny, transport-level read-only allowlist, and per-tool UI approval (PR #617 review, P1). Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
1c37080ed9 |
fix(research): bound audit redaction, reader limit, and memory prefix
Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
0a12cdb1c9 |
fix(research): accept existing DESIGN.md / craft shape in skill-hub
Address PR #617 review comment PRRC_kwDOSOgY8s6-ULyy: the previous frontmatter validator rejected the 140+ design systems and the craft modules Open Design already ships, since those files use a plain Markdown shape (`# <Heading>` plus `> Category:` blockquote) rather than YAML frontmatter. A hub repo mirroring the existing artifacts would have returned no entries from `listHubEntries()` and thrown from `installHubEntry()`, which defeats the starter's stated purpose. Add a heading-based fallback for `design-systems` and `craft`: - `deriveHeadingDescription(raw)` reads the first `# ` heading and the first blockquote block (cap 280 chars), stripping any frontmatter that may have been present. - `resolveManifest(namespace, raw, manifestId)` keeps `skills` strict (frontmatter required, since all 65+ shipped skills carry `name` / `description`) but accepts either frontmatter or the plain-Markdown shape for `design-systems` and `craft`. The manifest id is still re-validated against the namespace's slug rules to keep path-traversal guards intact, and any `name` or `od.mode` present in frontmatter must still be valid. - `readDirEntry`, `readFileEntry`, and `installHubEntry` route through `resolveManifest` instead of `validateFrontmatter`. `validateFrontmatter` itself stays as-is (still strict, still exported) so the v0 schema remains documented for hubs that opt into frontmatter. Sanity-checked against `design-systems/apple/DESIGN.md`, `design-systems/atelier-zero/DESIGN.md`, and `craft/accessibility-baseline.md`: all three now resolve to non-null entries with sensible derived descriptions, while `resolveManifest('skills', appleRaw, 'apple')` still returns null. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
897e477277 |
fix(research): reject "."/".." project ids and split audit-file resolver
Address two follow-up review comments on PR #617: - isSafeProjectId: explicitly reject "." and "..". The existing character allowlist `[A-Za-z0-9._-]{1,128}` accepted bare-dot ids, and the defense-in-depth check still permitted `dir === projectsRoot`, so `projectId="."` would have written `audit.jsonl` directly under `<dataDir>/projects/`. Tighten the strict-prefix check to require a proper subpath of the projects root. - Split path resolution from directory creation per reviewer's suggested shape: rename `resolveAuditPath` to `auditFilePath` (pure resolver, returns the full file path as a `string`) and have `ensureAuditFile` call it then `mkdirSync(path.dirname(file))`. `appendAuditEntry` continues to call ensure, `readAuditEntries` calls the pure resolver only — reads cannot create directories. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
8d4e940183 |
fix(research): harden memory/audit/hub starters per PR review
Address P1/P2 security review feedback on the unwired research starters under apps/daemon/src/research/: - memory-schema.ts (P1 prompt injection): reject control characters and prompt-frame tokens at create/update time, render entries as <-escaped JSON in `buildMemoryPrefix`, and reword the wrapper to mark memory as user-provided context rather than authoritative instructions. Also clamp the LIMIT in `listMemoriesForContext` to a finite integer and bind it as `LIMIT ?` instead of interpolating. - audit-log.ts (P1 path traversal + P2 redaction no-op): split path resolution from `mkdirSync` so reads are side-effect-free; add a recursive redactor that strips token / api_key / authorization / cookie / password / private_key / session_id / bearer / x-api-key fields before append and on export, with a per-string length cap and bounded recursion depth. - skill-hub.ts (P2 download cap + frontmatter validation): replace `arrayBuffer()` with a streamed reader that bails on Content-Length over the cap and cancels mid-download once accumulated bytes exceed it; replace the description-only regex with a minimal frontmatter parser plus per-namespace validation (name slug + manifest-id match, description required, `od.mode` allowlist) applied on both list and install paths. No runtime wiring changes; module remains unimported by server.ts. Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
f7ffce26eb |
fix(research): guard project id in audit-log starter
Validate `projectId` against the same `^[A-Za-z0-9._-]{1,128}$` allowlist
that `apps/daemon/src/projects.ts#isSafeId` uses, and verify the resolved
audit directory stays under `<root>/projects/`, before `mkdirSync()`.
Prevents a path-traversal bug if this starter is wired to the planned
`GET /api/projects/:id/audit` route with a malformed `:id`.
Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)
|
||
|
|
4f23f34bf2 |
fix(research): respect includeArchived; install craft at root
Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code) |
||
|
|
2f55171595 |
docs(research): openwork / AionUi / alaude-desktop integration analysis
Adds a deep capability survey of three external Agent-client projects and a minimum integration starter for Open Design. - docs/research/openwork-aionui-alaude-integration.md: full analysis, capability matrix, P0/P1/P2 extraction list with rationale, roadmap, and pitfalls. Each item carries "why useful" + "why open-design needs it" + minimum landing form. - apps/daemon/src/research/: standalone TypeScript starters for the three highest-ROI items (memory schema + injection helper, audit log JSONL writer/reader, GitHub-as-registry skill hub fetcher). NOT wired into server.ts; subdir README states the integration path for follow- up PRs (one PR per item, with contracts DTOs and tests). Validation: pnpm guard + pnpm --filter @open-design/daemon typecheck. |
||
|
|
f1290a0222 |
docs(readme): also surface help-wanted issues from first-PR link (#605)
GitHub's `/contribute` page only renders the `good first issue` label, so 12 open `help wanted` issues never reach newcomers via that entry. Switch the link to an issues search URL covering both labels (OR), so both pools surface from one click. Wording is unchanged across all 10 README locales. |
||
|
|
2036ce0a8e |
feat(web): add Cmd/Ctrl+P quick file switcher (#556)
* feat(web): add Cmd/Ctrl+P quick file switcher A keyboard-driven file palette overlaid on the workspace. Press Cmd/Ctrl+P anywhere in the project view; type to fuzzy-filter the file list, ↑/↓ to navigate, Enter to open in a tab, Esc to dismiss. With an empty query the palette surfaces recents (per-project, localStorage) followed by the rest of the file list sorted by mtime. Adds: - apps/web/src/components/QuickSwitcher.tsx: palette UI and matcher - apps/web/src/quickSwitcherRecents.ts: per-project recents store - index.css: scoped .qs-* styles using existing design tokens - i18n: 6 new keys translated across all 16 locale files Wires into FileWorkspace's existing openFile() so recents and tab state behave identically to opening from DesignFilesPanel. Capture-phase keydown beats the browser's print dialog. No backend changes; uses the files prop already passed to FileWorkspace. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(web): address QuickSwitcher review feedback Three fixes from the PR review: - z-index: bump .qs-overlay from 200 to 1500 so the palette renders in the modal tier (alongside prompt-template-modal-overlay) instead of behind context menus and popovers (which sit at 200). - Arrow-key guard: skip setCursor when matches is empty. Without this, pressing ↓ on a no-results query set the cursor to -1, making the highlight selector miss every row on the next render. - Tests: add 19 unit tests covering scoreMatch ranking tiers, render output (empty state / row count / kbd hints / placeholder), and the full recents lifecycle (cap at 6, dedupe-on-push, corrupt-JSON recovery, per-project scoping, quota-exceeded no-op). Vitest stays on the node env via a small in-memory localStorage stub. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(web): QuickSwitcher review — wrap, IME, platform gate Three follow-ups from @mrcfps's review on #556: - ArrowUp/ArrowDown now wrap at list bounds (last → first, first → last) via modulo arithmetic in a new pure helper `nextCursor(current, total, direction)`. Previously they clamped, which contradicted the wrap behavior the PR test plan promised. Pulled into a pure function so boundary cases are unit-testable without simulating keyboard events. - Palette's onKeyDown now early-returns on `e.nativeEvent.isComposing`, so users typing CJK file names through an IME keep ↑/↓/Enter for candidate navigation instead of having them steered by the palette. The global Cmd/Ctrl+P opener already had the equivalent guard. - Global keydown is now platform-gated: macOS responds only to metaKey, win/linux only to ctrlKey. Previously both fired everywhere, which meant Ctrl+P on macOS was stealing native readline "previous line" in text fields (and the chat composer). Tests: +6 unit tests for `nextCursor` covering forward/backward wrap, mid-list moves, empty list (no division-by-zero), and single-item no-op. Suite now 258 passing (up from 252). Verified live: ↓ from last row → first row; ↑ from first row → last row, in a mocked-project Playwright harness. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
e8b63ecec1 | feat: add resizable chat panel (#563) | ||
|
|
241846e1ef |
Update docs/assets/github-metrics.svg - [Skip GitHub Action] (#592)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> |
||
|
|
b064637e3f |
feat(craft): accessibility-baseline module + opt-ins on dashboard, hr-onboarding, mobile-onboarding (#587)
* feat(craft): add accessibility-baseline + opt-ins on dashboard, hr-onboarding, mobile-onboarding Module 3 of 5 in the behavioral craft series proposed in #501. Modules 1 (state-coverage, #502) and 2 (animation-discipline, #515) merged earlier today. The differentiator that survived the corpus review is native-mobile parity. Existing OSS prior art (fecarrico/A11Y.md, awesome-copilot, Community-Access) covers web ARIA well, none covers Flutter Semantics, Compose semantics, iOS UIKit/SwiftUI, or RN labelling APIs. Secondary differentiator: jurisdictional legal-floor calibration. EAA references WCAG 2.1 (via EN 301 549 v3.2.1), not 2.2. ADA Title II 2026-04-24 deadline slipped to 2027-04-26 via 2026-04-20 IFR. Most existing OSS a11y prior art doesn't track either accurately. Three-loop adversarial review pass before push (codex unavailable, ran via substitute agent). Loop 1 caught nine cuts plus four factual fixes including a wrong Android Compose API name. Loop 2 verified and flagged two more trims. Loop 3 said ship. Anchored citations: WCAG 2.2 Understanding pages, ISO/IEC 40500:2025, ADA Title II 2024 + 2026-04-20 IFR, EN 301 549 v3.2.1, WAI-ARIA 1.3 + AccName 1.2 + Core AAM 1.2, WebAIM Million 2025, A11yn (arXiv 2510.13914), APCA W3C silver branch. Refs #501. * fix(craft): accessibility-baseline review fixes (lefarcen + mrcfps) Address all P1/P2/P3 findings: - P1 (lefarcen): add "Keyboard operability and semantic structure" section covering tab reachability (2.1.1), activation keys, no keyboard trap (2.1.2), focus order (2.4.3), native-control-first, document language (3.1.1), heading hierarchy (1.3.1, 2.4.6), landmarks (1.3.1, 2.4.1), text alternatives (1.1.1) - P2 (lefarcen): expand jurisdiction scope with US Section 508 (WCAG 2.0 AA), ADA Title III caveat, EU WAD reference - P2 (lefarcen + mrcfps): rename contrast-table row to "Normal text below 18 pt regular / 14 pt bold" so the table matches the threshold rule - P2 (mrcfps): correct "exclusive" → "inclusive" — exact 4.5:1 / 3:1 passes; the no-rounding rule is what makes 2.999:1 fail - P2 (lefarcen): add "Prior art and scope" note differentiating from existing OSS a11y agent docs - P3 (lefarcen): narrow APCA framing to "not part of WCAG/EN/ADA/Section 508" and clarify size/weight-dependent thresholds - P3 (lefarcen): expand WCAG 2.5.8 exceptions list (Spacing, Equivalent, Inline, User Agent Control, Essential) - Common-mistakes additions: Section 508/2.1 confusion, tabindex>0 anti-pattern, modal-focus-trap distinction from 2.1.2, heading-size vs level confusion * fix(craft): accessibility-baseline mrcfps round-2 precision fixes All three non-blocking precision items addressed: - Update WebAIM Million benchmark from 2025 to 2026 (February 2026 crawl). Form labels: page-level 51% (was 48.2%), input-level 33.1% (was 34.2%) of 6.9M inputs (was 6.3M). ARIA: 59.1 errors on ARIA pages vs 42 on non-ARIA (was 57 vs 27); gap is ~17 in 2026, was 30 in 2025. ARIA usage 82.7% of pages (was 79.4%). Verified directly against webaim.org/projects/million/. - Soften keyboard/semantic-structure intro: Level A items are still labeled Level A, but 2.4.6 Headings and Labels is correctly tagged AA, and the one-h1 / no-skipped-levels rules are now framed as OD craft conventions on top of WCAG's programmatic-structure floor (1.3.1). - Tighten <a> activation note: bare <a> without href is not focusable, not a link, and not keyboard-operable. Use <a href="…"> for navigation or <button> for actions. Added a "common mistakes" entry to lock the rule. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
||
|
|
14a73d948b |
Fix packaged contracts runtime exports (#577)
* fix packaged contracts runtime exports * fix(packaging): prepare contracts runtime exports on install |
||
|
|
b8adcd0670 |
docs: add Chinese (Simplified) QUICKSTART (#578)
Translate QUICKSTART.md to QUICKSTART.zh-CN.md and add the 简体中文 entry to the language nav in all existing translations (en / de / fr / ja-JP / pt-BR). |
||
|
|
581baeebb7 |
docs(readme): document OD_DATA_DIR + migration from .od/ to Desktop app (#570)
* docs(readme): document OD_DATA_DIR + migration from .od/ to Desktop app
The "Move it elsewhere" row in the First-run state table still said the
path is hard-coded; OD_DATA_DIR (resolveDataDir in apps/daemon/src/server.ts)
has supported relocation since the runtime-data refactor. Replace the
"not supported yet" note with the actual env-var usage and resolution
semantics, and add OD_MEDIA_CONFIG_DIR for the narrower credentials
override.
Add a Migrating a pre-desktop-app `.od/` section so users who started in
the repo and later installed the packaged Desktop app know:
- the two writers target different roots (repo .od/ vs.
~/Library/Application Support/.../namespaces/<channel>/data on macOS,
with the platform-equivalent paths on Windows and Linux),
- how to copy projects/SQLite/artifacts/media-config.json over after
quitting the app cleanly,
- how to keep both writers on the same dir going forward via
OD_DATA_DIR.
Documentation only; no code changes.
* docs(readme): address review feedback on .od/ migration section
Resolves the review on #570:
- chatgpt-codex P1 / mrcfps: replace the literal `<repo>` token in the
copy command (Bash parses `<repo>` as input redirection, so the
documented snippet would fail before any copy). Use a shell-safe
`REPO=` variable in the example.
- chatgpt-codex P2 / mrcfps / lefarcen P2: correct the cross-platform
Desktop data-root. The packaged runtime resolves
`app.getPath("userData")/namespaces/<namespace>/data` (see
apps/packaged/src/config.ts:106-107), and Electron's `userData`
default on Linux is `$XDG_CONFIG_HOME` / `~/.config`, not
`$XDG_DATA_HOME`. Replace the single macOS-only path with a per-OS
table, plus a hint to inspect the packaged daemon log for the
resolved `daemonDataRoot`.
- lefarcen P2: list platform-specific channel namespaces. The release
workflows append `-win` and `-linux` suffixes (release-stable-win,
release-beta-win, release-stable-linux, release-beta-linux); only
macOS uses the bare `release-stable`/`release-beta` strings.
- lefarcen P1 (data corruption): demote the "share one data dir between
repo dev-server and Desktop app" recommendation to an Advanced
callout with an explicit warning that the two writers must never run
at the same time. The daemon opens app.sqlite in WAL mode and writes
uncoordinated project/artifact files, so concurrent use can corrupt
SQLite or clobber artifacts.
- lefarcen P2 (downgrade risk): add a forward-only schema migration
warning. apps/daemon/src/db.ts applies `CREATE TABLE IF NOT EXISTS` /
`ALTER TABLE` without a version guard, so opening a migrated dir with
an older repo checkout can leave the workspace inconsistent. Advise
backing up app.sqlite* before the first launch.
- lefarcen P2 (failure-safety): replace the in-place `cp -R` with a
rsync-into-sibling-then-rename pattern so a partial copy cannot leave
the Desktop data dir in a half-populated state. Document the restore
path from the .fresh-baseline-* backup.
- lefarcen P2 (replace vs merge): add a preflight `ls` of the Desktop's
existing projects and a callout that this is a replace operation, so
users with projects on both sides can stop and choose which is
authoritative.
Documentation only.
* docs(readme): address second review round on .od/ migration section
Resolves the follow-up review on #570 from
|
||
|
|
c69dee74a5 | fix(release): defer Linux artifact from 0.4.0 stable open-design-v0.4.0 | ||
|
|
036e105b98 | Add spanish readme (#552) | ||
|
|
29e1ed5f28 | fix: 修复设计文件列表行菜单被裁剪的问题 (#561) | ||
|
|
6b2792b03a |
fix(daemon): remove --no-session from pi adapter to persist session files (#557)
* fix(daemon): remove --no-session from pi adapter to persist session files The pi agent was the only adapter explicitly passing `--no-session` in its `buildArgs`, preventing pi from writing session files. All other adapters either run in single-shot mode by design or use the ACP JSON-RPC session lifecycle without suppressing persistence. Removing `--no-session` lets `--mode rpc` retain its default behavior of writing session state, which is needed for multi-prompt continuity and matches the rest of the harness ecosystem. * test(daemon): add pi buildArgs regression tests; fix docs for --no-session removal - Adds test for pi.buildArgs base shape: returns ["--mode", "rpc"] and does not include --no-session (prevents regression). - Adds test for --model and --thinking option passthrough. - Updates pi-rpc.ts lifecycle comment to remove [--no-session]. - Updates README.md and all localized READMEs to reflect the corrected pi CLI invocation. |
||
|
|
74f1a18b71 | fix(tools-pack): replace corepack with npx in linux container build (#558) | ||
|
|
0953ab58a2 |
fix(web): todo card dark mode styling (#526)
* fix(web): improve todo card dark mode * fix(web): address todo card contrast feedback Generated-By: looper 0.5.5 (runner=fixer, agent=opencode) |
||
|
|
963bbf2500 | release: Open Design 0.4.0 (#454) | ||
|
|
009d7a5478 |
refactor(daemon): eliminate duplicate dist tree from two-tsconfig build (#553)
Move sidecar source under src/ so a single tsconfig produces all daemon
output. Removes the parallel dist/src/ tree that was emitted by
tsconfig.sidecar.json (it included src/**/*.ts to type-check the
`../src/server.js` cross-tree import).
Build now emits:
- dist/<flat> (cli.js, server.js, app-version.js, ...)
- dist/sidecar/{index,server}.js
`dist/sidecar/server.js` reaches the main daemon via `../server.js`
instead of `../src/server.js`, so there is no second copy of the source
tree in the published tarball.
Background — issue #534 (already fixed by #537):
The packaged Settings → About panel showed 0.0.0 because the sidecar
chain loaded the duplicated `dist/src/app-version.js`, where the fixed
`new URL('../package.json', import.meta.url)` resolved to a non-existent
`dist/package.json`. #537 patched the symptom by walking parents until a
real `package.json` is found and by writing `appVersion` into the Linux
packaged config. Both stay in place — they're sound defenses — but the
underlying duplicate-emit was never addressed; any future relative
resource lookup (templates, schemas, prompts) anchored on
`import.meta.url` would have hit the same trap.
This change removes the trap.
|
||
|
|
6b7a40e5c3 | Fix file tab wheel scrolling (#549) | ||
|
|
14908e1aea | fix: typo in zh-TW README (#548) | ||
|
|
cbe2baf596 |
feat(web): add skills & design systems management page in settings (#535)
* feat(web): add skills & design systems management page in settings Add a new "Library" section in Settings that lets users browse, search, preview, and enable/disable skills and design systems. Disabled items are excluded from the create-project picker. Phase 1 — browse/toggle only. Closes #497 * fix(web): persist empty disabled lists and deduplicate DS preview Use empty array instead of undefined when all items are re-enabled so the daemon merge clears the key. Move DS preview panel outside the category group loop so it renders once, not per group. * fix(web): address review feedback on library settings Clear disabled lists on invalid daemon writes, memoize enabled item filters in App.tsx, and guard preview fetch against rapid-click race conditions. * fix(web): hydrate disabled lists from daemon and keep full lists in ProjectView Merge daemonConfig.disabledSkills/disabledDesignSystems during bootstrap so the values survive localStorage resets. Pass unfiltered skills and design systems to ProjectView so existing project metadata resolves correctly. |
||
|
|
4fa2df2ae3 |
docs(i18n): defer README template-driven generation, capture #195 discussion (#403)
Add NRG / template-driven README generation to TRANSLATIONS.md "Deferred decisions" with explicit re-evaluation triggers (≥15 locales or monthly+ README structural edits) and a record of the shared-structure trade-off that surfaced in #195. Captures the rationale (zh-TW's "上手體驗" section, pt-BR vs pt-PT content-level divergence precedent) so future contributors don't relitigate it from scratch. |
||
|
|
cc6da191e8 |
fix(version): resolve daemon package.json from any compiled layout (#537)
Settings -> About used to display 0.0.0 in packaged builds because `readCurrentAppVersionInfo` resolved `'../package.json'` relative to `import.meta.url`, which only points at the daemon package root from the flat CLI build (`dist/app-version.js`). The sidecar build emits `dist/src/app-version.js`, where the same relative path lands on the non-existent `dist/package.json`, so `readPackageMetadata` returned null and the version fell back to APP_VERSION_FALLBACK. Walk up from `import.meta.url` to find the nearest real `package.json` instead, so the daemon reports its actual version regardless of whether it runs from TypeScript source (tools-dev), the flat CLI dist, or the nested sidecar dist used by the packaged desktop app. The OD_APP_VERSION env still wins inside `resolveAppVersionInfo`, so callers that already inject it (mac/win packagers) keep working. Also write `appVersion` into the Linux packaged config so Linux follows the same env-injection path as mac/win and stays consistent with the new fallback resolution. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
79fcaef129 |
Add Tweaks mode for HTML previews with picker, pod selection, and batched chat attachments (#513)
* Add tweaks mode for HTML preview comments * Fix tweaks geometry and restore critique migration * Harden tweaks mode reload sync * Guard tweaks batch sends during active runs --------- Co-authored-by: puma <puma@pumas-MacBook-Air.local> |
||
|
|
34e8db175d |
fix(daemon): preserve ANTHROPIC_API_KEY when ANTHROPIC_BASE_URL is set (#514)
* fix(daemon): preserve ANTHROPIC_API_KEY when ANTHROPIC_BASE_URL is set The claude adapter currently strips ANTHROPIC_API_KEY unconditionally so that Claude Code's own auth resolution (claude login) wins instead of silently falling back to API-key billing. However, when ANTHROPIC_BASE_URL is set the user is intentionally routing Claude Code to a custom endpoint (e.g. a Kimi/Moonshot proxy). In that case claude login is meaningless, so preserve the API key so the child can authenticate against the custom base URL. * fix(daemon): guard against empty ANTHROPIC_BASE_URL values Address review feedback: check that ANTHROPIC_BASE_URL contains a non-empty, non-whitespace string before preserving ANTHROPIC_API_KEY. This prevents the #398 billing guard from being bypassed when the variable is set to '' or whitespace. |
||
|
|
e5c9febf8c |
docs: surface desktop downloads in README badges and Quickstart (#522)
Desktop client v0.3.0 has shipped for macOS (Apple Silicon) and Windows (x64) at https://open-design.ai/ and the GitHub releases page. Surface that in 11 READMEs (en + 10 localized): - Add a 'Download' CTA badge as the first item in the shields row, linking to open-design.ai (orange #ff6b35, no platform-specific logo so it doesn't imply Mac-only or Windows-only). - Repoint the existing release badge link from /releases/latest to /releases (the general entry page, more stable for users browsing history). - Add &display_name=tag to the release shields URL so the badge shows the literal tag (e.g. open-design-v0.3.1-beta.5) instead of 'invalid' — shields.io's semver parser doesn't recognize the open-design- prefix. - Update the At-a-glance 'Deployable to' row: drop the 'placeholder, in-flight' note and call out the actual macOS/Windows downloads with links to open-design.ai and the releases page. - Insert a 'Download the desktop app (no build required)' subsection at the top of Quickstart, with a 'Run from source' subheading before the existing bash block — splits the funnel between non-developer users (download link) and developers (clone + pnpm). - Flip the roadmap entry for apps/packaged/ from [ ] to [x] and append the download links. zh-TW does not carry the release badge in its shields row, so the release-badge update is a no-op there; all other changes apply. |
||
|
|
e0a75ea8c8 |
fix: add lowercase 'todowrite' compatibility in ToolCard (#523)
Add backward compatibility for historic OpenCode CLI data: - Match both 'TodoWrite' and 'todowrite' tool names - Fixes rendering of TodoWrite cards from persisted chat history Scope: 1 line change, no other files modified Co-authored-by: bojiehuang <bojiehuang@bojiehuangdeMacBook-Pro.local> |
||
|
|
5da21e4054 |
feat(craft): animation-discipline module + opt-ins on mobile-app, mobile-onboarding, gamified-app (#515)
* feat(craft): add animation-discipline + opt-ins on mobile-app, mobile-onboarding, gamified-app Animation discipline is the second behavioral craft module proposed in #501 and explicitly invited in @mrcfps's post-merge comment on #502. Differentiation from prior art (LottieFiles motion-design-skill, MIT, 96 stars): citation-grounded against primary sources rather than asserted. Anchors: - Tversky/Morrison/Bétrancourt 2002 (IJHCS) on the one demonstrated win-condition for animation - Heer & Robertson TVCG 2007 on staging (with the actual durations they tested, not the laundered '300-1000ms' rule) - Harrison/Yeo/Hudson CHI 2010 on perceived-duration scope (progress bars only, not skeletons) - Doherty & Thadani IBM 1982 productivity numbers - Material 3 motion tokens (M3 standard vs M2 legacy delta) - IBM @carbon/motion durations - Apple SwiftUI Animation API published defaults - W3C View Transitions API + WCAG 2.2.2/2.3.3 calibration - WebKit 2017 prefers-reduced-motion rationale The 'common mistakes (lint these)' section busts five specific folklore claims that don't survive primary-source check, including the Doherty-400ms attribution and the M2-vs-M3 standard easing confusion. Three skills opt in via od.craft.requires: - mobile-app (animation-heavy mobile screens) - mobile-onboarding (multi-screen flow with transitions) - gamified-app (animations central to the format) Refs #501. * fix(craft): address review findings on animation-discipline Six findings from @lefarcen's CHANGES_REQUESTED review on #515, addressed in one pass. Reviewed by codex across three loops before push. P1 integration gaps: - gamified-app and mobile-onboarding skills now require both state-coverage and animation-discipline (both render stateful UI with motion). - craft/README.md silent-fallback example reframed as a planned-but-not-yet-vendored placeholder rather than a hard-coded next-to-ship slug. Note added pointing skill authors who arrive from older guidance at animation-discipline as the equivalent of the earlier 'motion' placeholder. P2 reasoning completeness: - > 500 ms duration row reframed: 'Reserved for cross-screen, staged, or platform-native transitions (e.g. M3 long2-extraLong4, Heer & Robertson 2007's per-stage recommendation)'. Surrounding paragraph rewritten with an enumerated category — 'Non-navigation microinteractions: hover, press, toggle, validation, chip selection, row expansion' — rather than the vague 'routine' term. - New 'Flashing limits' subsection added in the Reduced motion section. WCAG 2.3.1 (Level A) three-flashes-in-any-one-second-period rule with the area/brightness threshold qualifier; WCAG 2.3.2 (AAA) unconditional rule. Photosensitive epilepsy framing. - New 'Repeated and ambient motion' section added. Five rules covering iteration cap, WCAG 2.2.2 pause control after 5s, cancel-on-route, one-shot reward animations, and spinner timeout cross-referencing state-coverage.md. File length now 154 lines (was 130, 80-110 craft target). Trade is citation density and the new sections demanded by the integration context (gamified/onboarding skills with looping motion). Refs #501, #515. |
||
|
|
c3d9136a0c |
Add live artifacts and Composio connector catalog (#381)
* docs: add live artifacts implementation spec * docs: align live artifacts implementation plan * Ralph iteration 1: work in progress * Ralph iteration 2: work in progress * Ralph iteration 3: work in progress * Ralph iteration 4: work in progress * Ralph iteration 5: work in progress * Ralph iteration 6: work in progress * Ralph iteration 7: work in progress * Ralph iteration 8: work in progress * Ralph iteration 9: work in progress * Ralph iteration 10: work in progress * Ralph iteration 11: work in progress * Ralph iteration 12: work in progress * Ralph iteration 13: work in progress * Ralph iteration 14: work in progress * Ralph iteration 15: work in progress * Ralph iteration 16: work in progress * Ralph iteration 17: work in progress * Ralph iteration 18: work in progress * Ralph iteration 19: work in progress * Ralph iteration 20: work in progress * Ralph iteration 21: work in progress * Ralph iteration 22: work in progress * Ralph iteration 23: work in progress * Ralph iteration 24: work in progress * Ralph iteration 25: work in progress * Ralph iteration 26: work in progress * Ralph iteration 27: work in progress * Ralph iteration 28: work in progress * Ralph iteration 29: work in progress * Ralph iteration 30: work in progress * Ralph iteration 31: work in progress * Ralph iteration 32: work in progress * Ralph iteration 33: work in progress * Ralph iteration 34: work in progress * Ralph iteration 35: work in progress * Ralph iteration 36: work in progress * Ralph iteration 37: work in progress * Ralph iteration 38: work in progress * Ralph iteration 39: work in progress * Ralph iteration 40: work in progress * Ralph iteration 41: work in progress * Ralph iteration 42: work in progress * Ralph iteration 43: work in progress * Ralph iteration 44: work in progress * Ralph iteration 45: work in progress * Ralph iteration 46: work in progress * Ralph iteration 47: work in progress * Ralph iteration 48: work in progress * Ralph iteration 49: work in progress * Ralph iteration 50: work in progress * Ralph iteration 51: work in progress * Ralph iteration 52: work in progress * Ralph iteration 53: work in progress * Ralph iteration 54: work in progress * Ralph iteration 55: work in progress * Ralph iteration 56: work in progress * Ralph iteration 57: work in progress * Ralph iteration 58: work in progress * Ralph iteration 59: work in progress * Ralph iteration 60: work in progress * Ralph iteration 61: work in progress * Ralph iteration 62: work in progress * Ralph iteration 63: work in progress * Ralph iteration 64: work in progress * Ralph iteration 65: work in progress * Ralph iteration 1: work in progress * Ralph iteration 2: work in progress * Ralph iteration 3: work in progress * Ralph iteration 4: work in progress * Ralph iteration 5: work in progress * Ralph iteration 6: work in progress * Ralph iteration 8: work in progress * Ralph iteration 9: work in progress * Ralph iteration 17: work in progress * Add Composio-backed connectors * Add Composio-backed connector catalog * Fix connector callback flow * Update live artifact connector refresh * Fix live artifact refresh updates * Improve live artifact viewer toolbar * Refine live artifact source tabs * Expand Composio connector catalog * Improve Composio connector browsing * Fix artifact refresh source safety checks Generated-By: looper 0.4.1 (runner=fixer, agent=opencode) * Fix live artifacts PR feedback Generated-By: looper 0.5.0 (runner=fixer, agent=opencode) * Fix live artifact preview CORS validation Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * Fix connector OAuth IPv6 loopback hosts Allow bracketed IPv6 loopback Host headers when deriving connector OAuth callback URLs so IPv6-bound daemons can complete connection flow. Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * Preserve live artifact refresh permissions Respect explicit refresh permission choices during live artifact create and update flows so revoked connector sources remain gated. Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * Fix live artifact preview cache freshness Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * Fix live artifact refresh validation Guard manual refreshes with local daemon checks and reject daemon_tool sources without a toolName before refresh execution. Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * Fix Composio credential invalidation Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * Fix live artifact CORS methods Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * Fix workspace validation Restore media config test isolation under Vitest setup data-dir overrides and add the missing French live artifact display copy so the workspace test suite stays aligned.\n\nGenerated-By: looper 0.5.2 (runner=fixer, agent=opencode) * Fix connector safety filtering Keep agent-preview connector listings aligned with execution safety policy and prune stale Composio OAuth state records before they accumulate. Generated-By: looper 0.5.2 (runner=fixer, agent=opencode) * Fix agent runtime cleanup Generated-By: looper 0.5.2 (runner=fixer, agent=opencode) * Fix live artifact daemon access Validate local-only live artifact routes against the peer socket address and pass daemon-resolved CLI paths to ACP MCP descriptors.\n\nGenerated-By: looper 0.5.2 (runner=fixer, agent=opencode) * Fix connector run limit pruning Evict stale connector rate-limit buckets so long-lived daemon processes do not retain per-run entries indefinitely.\n\nGenerated-By: looper 0.5.2 (runner=fixer, agent=opencode) * Fix connector compact schemas Generated-By: looper 0.5.2 (runner=fixer, agent=opencode) * Improve connector connection feedback * Adjust connector gate positioning * Fix live artifact refresh commits Avoid marking refresh candidates failed after snapshot or state persistence errors by deferring live artifact mutations until the durable refresh metadata is written. Also align connector OAuth callback host validation with daemon loopback handling.\n\nGenerated-By: looper 0.5.4 (runner=fixer, agent=opencode) * Improve connector search relevance * fix(daemon): harden connector connection state Require loopback daemon validation before connector connect side effects and only clear provider-owned connector statuses during credential reset. Generated-By: looper 0.5.4 (runner=fixer, agent=opencode) * fix(daemon): guard connector disconnect route Require local daemon request validation before connector disconnect side effects. Generated-By: looper 0.5.4 (runner=fixer, agent=opencode) * fix(daemon): guard composio config updates Generated-By: looper 0.5.4 (runner=fixer, agent=opencode) * fix(daemon): dispatch live artifacts mcp first Route the live-artifacts MCP server before the generic MCP CLI so od mcp live-artifacts starts the dedicated server instead of failing generic argument parsing.\n\nGenerated-By: looper 0.5.4 (runner=fixer, agent=opencode) * fix(daemon): handle integer connector schemas Allow JSON Schema integer connector inputs while preserving fractional-value validation so generated connector tool schemas accept valid page sizes and limits. Generated-By: looper 0.5.4 (runner=fixer, agent=opencode) * fix: align live artifact refresh error codes Generated-By: looper 0.5.4 (runner=fixer, agent=opencode) * Fix live artifact connector refresh flow * Update live artifact design cards * Add beta badge to live artifact form * Remove live artifact tile model * Fix live artifact refresh sync * Fix live artifact MCP refresh durability Generated-By: looper 0.5.4 (runner=fixer, agent=opencode) * Fix live artifact refresh safety Enforce persisted refresh opt-out and connector auto-read gating before refresh sources execute. Generated-By: looper 0.5.5 (runner=fixer, agent=opencode) |
||
|
|
ab58b62b17 |
feat(craft): state-coverage module + opt-ins on dashboard, mobile-app, kanban-board (#502)
* feat(craft): add state-coverage rules + opt-ins on dashboard, mobile-app, kanban-board
State coverage is the most reliable AI-design failure: agents ship only the
populated state. This adds craft/state-coverage.md (108 lines, matches the
existing craft format) covering the five required states (loading, empty,
error, populated, edge), three form-specific states, ARIA/focus rules, and
loading-duration thresholds.
Sources are public: WCAG 2.2, NN/g, Material Design 3, Apple HIG, Baymard.
Three skills with stateful UI opt in via od.craft.requires:
- dashboard
- mobile-app
- kanban-board
Decks, ppt, image-poster and other static-output skills do not opt in.
Refs: see issue body for the broader proposal (state-coverage is module 1
of 5 behavioral craft modules).
* fix(craft): address review findings on state-coverage
Four P2 findings from #502 review addressed in one pass.
- Edge state Test matrix added under the five-states table (dashboard,
mobile, form, search, detail-view scenarios with concrete thresholds).
- Server-driven empty pattern added as trailing note in the empty-state
composition section.
- Retry discipline subsection added after error severity tiers
(immediate first retry, exponential 2s/4s/8s backoff, 3-retry floor,
Last-attempted timestamp).
- README enforcement-levels subsection added distinguishing auto-checked
P0 rules from guidance; partial-stateful skill clarification added
after the Files table.
No rewrites. ~30 lines added. File stays inside the 80-110-line craft
target.
* fix(craft): correct lint enforcement claim + remove duplicate threshold message
Two findings from @mrcfps review (Looper-generated against
|
||
|
|
76e6c7a9f6 |
feat: Critique Theater Phase 4 (persistence + transcript + orchestrator) (#481)
* docs(specs): add Critique Theater design spec for panel-tempered artifacts * docs(specs): add Critique Theater implementation plan * docs(specs): rename UI to Design Jury, add lane-density modes, ship-rule explainer, label sizing * feat(contracts): add CritiqueConfig schema and defaults * fix(contracts): apply Task 1.1 review (CRITIQUE_PROTOCOL_VERSION rename, descriptions, RoleWeights export) * feat(contracts): add PanelEvent discriminated union and isPanelEvent guard * fix(contracts): apply Task 1.2 review (exhaustive event-type list, runId guard, import order) * feat(contracts): add CritiqueSseEvent variants and panelEventToSse mapper * test(daemon): add v1 wire-protocol golden fixtures for Critique Theater parser * feat(daemon): add v1 streaming parser for Critique Theater wire protocol * chore(contracts): add .js extensions to relative imports for NodeNext consumers * fix(daemon): satisfy noUncheckedIndexedAccess in v1 parser regex match access * test(daemon): cover parser failure modes; fix unclosed-PANELIST swallow bug * fix(daemon,contracts): address PR #387 review - parser now clamps panelist + DIM scores against the run-declared scale captured from <CRITIQUE_RUN scale=...>, not a hardcoded 100 - PANELIST appearing before any <ROUND n=...> opens now throws MalformedBlockError rather than emitting events with NaN round - DIM_RE and MUST_FIX_RE hoisted to module scope and lastIndex reset per call so the parser hot path stops recompiling regex per artifact - overflow check after drain simplified to a plain buf.length > cap test (the prior compound condition was always true on the right side and obscured intent) - scoreThreshold <= scoreScale refine gains a 1e-9 epsilon so floating slack does not reject semantically valid configs - round-1 designer ARTIFACT guard gains a comment naming the spec invariant and the v2 relaxation path - 3 new regression tests cover the panelist-without-round, scale=10 clamp, and scale=20 plumbing cases * docs(specs): rationale for non-goals, failure-mode rate targets, Phase 10 matrix, Phase 14 doc layout * Merge branch 'main' into feat/critique-theater Resolves the contracts/index.ts conflict by keeping the .js extensions added by chore(contracts) |
||
|
|
bbdd4e84b5 |
chore: enforce test directory conventions (#496)
* 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. |
||
|
|
16693fdfa8 |
docs: add official Discord invite to README badges (#504)
Adds the official Discord community link (https://discord.gg/qhbcCH8Am4) as a badge in the badge row across all 11 localized READMEs so users have a clear, consistent entry point to the community. Co-authored-by: joey <joey@joeydeMacBook-Air.local> |
||
|
|
c2e3691130 |
docs: add Arabic (العربية) README translation (#458)
* docs: add Arabic README translation Adds README.ar.md — full Arabic translation of README.md, wrapped in a top-level <div dir="rtl"> for correct RTL rendering on GitHub. All URLs, file paths, code blocks, badges, and tables are preserved verbatim; prose and table cell text are translated to Modern Standard Arabic. Also wires up the language switcher in all nine sibling README files (en/de/fr/zh-CN/zh-TW/ko/ja-JP/ru/uk) so the previously-placeholder العربية entry now links to README.ar.md. The translation is an initial pass — native-Arabic-speaker review for phrasing/terminology is welcome. * docs(ar): preserve code fences verbatim and restore license attribution Address PR #458 review feedback (P2): 1. Revert translated prose inside fenced code blocks back to verbatim English, matching the source README.md: - Prompt-stack composition block - Architecture ASCII diagram (browser layer, daemon comments, bottom CLI row) - Quickstart bash comments - .od/ tree comments - Repository structure tree comments 2. Restore the License section's bundled-attribution sentence with links to skills/guizang-ppt/LICENSE (MIT, @op7418) and skills/html-ppt/LICENSE (MIT, @lewislulu); the previous version collapsed it to a generic 'see LICENSE' pointer. * docs(ar): translate Running the Project and MCP server sections Address PR #458 follow-up review (mrcfps): the Arabic README jumped from the .od/ first-run section straight to repository structure, missing the two sections added to README.md after this branch was forked: - ## Running the Project — web/localhost mode, fixed-port restarts, desktop/Electron commands, and the useful-commands table - ## Use Open Design from your coding agent — stdio MCP server setup, per-client install flow, daemon-must-be-running note, and the read-only security model Command blocks, table structure, and links are preserved verbatim from README.md per the same convention used elsewhere in the file. |
||
|
|
a3a0ae6ced |
fix(daemon): respect baseUrl path verbatim in OpenAI-compat proxy (#410)
* fix(daemon): respect baseUrl path verbatim in OpenAI-compat proxy `appendVersionedApiPath` previously force-injected `/v1` unless the supplied baseUrl ended with `/vN`. That broke any provider whose OpenAI-compatible surface lives under a sub-path: https://api.deepinfra.com/v1/openai → ".../v1/openai/v1/chat/completions" https://openrouter.ai/api/v1 → ".../api/v1/chat/completions" (worked, by luck of /vN suffix) Now the auto-`/v1` only fires when the user supplied no path at all, so DeepInfra, OpenRouter, and any other sub-path-mounted compat surface route to the right endpoint while the canonical `https://api.openai.com` / `https://api.anthropic.com` shortcuts still work. Adds a regression test table covering the matrix. * Account for Anthropic style URLs |
||
|
|
b5598572d8 |
fix(daemon): scope -32603 recovery to session/set_model request id (#492)
Address review feedback from lefarcen and mrcfps on PR #492: P1: Track setModelRequestId to scope the recovery block to the exact session/set_model request. This prevents duplicate prompt sends if session/prompt returns -32603 (which would otherwise match on expectedId + non-default model conditions). P1: Add promptRequestId === null guard so the recovery path only triggers before a prompt has been sent. P2: In detectAcpModels, only suppress -32603 on unexpected ids. Expected-id -32603 errors (initialize, session/new) are real probe failures and should reject immediately rather than causing a silent 15s timeout. P2: In attachAcpSession, expected-id -32603 errors that don't match setModelRequestId now call fail() instead of falling through. This prevents initialize/session/new/session/prompt failures from being silently swallowed. |
||
|
|
406a077ba7 |
docs(readme): point first-PR link to /contribute page (#494)
The `labels/good-first-issue` URL renders an empty list when no issues carry that label. GitHub's `/contribute` page auto-curates a mix of good-first-issue, help-wanted, and active items, so it stays useful for newcomers regardless of label coverage. Wording is unchanged across all 10 README locales. |
||
|
|
0ab98fed07 |
fix(daemon): correct Claude Code --add-dir capability detection (fix #430) (#440)
Probe 'claude -p --help' (subcommand help) instead of 'claude --help' (global help), because --add-dir and --include-partial-messages are subcommand-specific flags that do not appear in the global help output. Previously, successful capability probing would set caps.addDir = false because the flag was not found in global help, causing the daemon to never pass --add-dir to spawned Claude Code processes. This broke absolute-path reads for skill seeds and design-system specs, as Claude Code's sandbox policy blocks access to paths outside the project cwd unless explicitly allowed via --add-dir. The probing-failure / timeout path already worked correctly (empty caps object defaults to passing --add-dir). The failure manifested only when help probing succeeded and explicitly failed to locate the subcommand flags. Co-authored-by: bojiehuang <bojiehuang@bojiehuangdeMacBook-Pro.local> |