* feat(tools-dev): add --prod flag and OD_HOST for headless server deployment
- Lazy-load electronBinaryPath so daemon+web can start without Electron
- Add --prod flag to tools-dev start/run that sets NODE_ENV, OD_WEB_PROD,
and OD_WEB_OUTPUT_MODE automatically for production Next.js builds
- Add OD_HOST env var support to daemon and web sidecar bind addresses
(defaults to 127.0.0.1, set to 0.0.0.0 for remote access)
- Skip next.config.ts distDir override when OD_WEB_PROD=1 so production
builds resolve the default .next directory
Closes#221
* fix: address PR review — hardcode daemon bind to 127.0.0.1, cache electron path
- Revert OD_HOST from daemon: daemon is a local privileged process and must
only bind 127.0.0.1. Remote access goes through the web sidecar proxy.
- Web sidecar resolveDaemonOrigin now always uses 127.0.0.1, separated from
the web bind address (OD_HOST) so the daemon proxy works correctly even
when the web listener binds 0.0.0.0.
- Add OD_HOST character validation to reject clearly invalid values early.
- Cache electronBinaryPath getter result to avoid repeated require() calls.
---------
Co-authored-by: yamsfeer <yamsfeer@users.noreply.github.com>
* feat(web): pick prompt templates (not design systems) for image/video projects
The New Project panel now shows the curated prompt-template gallery in the
image and video tabs instead of the Design System picker. Design systems
only make sense for prototypes, slide decks, templates, and the freeform
"other" canvas — they don't map onto image/video generation.
The picked template's body is editable in-line ("optimize" affordance) and
the (possibly tuned) prompt is snapshotted into ProjectMetadata as
`promptTemplate`. The system-prompt composer surfaces it on every turn as
a stylistic + structural reference for the agent — same shape we already
use for the saved-template flow.
Also rename the right-side gallery tabs from "Image prompts" / "Video
prompts" to "Image templates" / "Video templates" across all locales.
Made-with: Cursor
* fix(prompt-templates): address review — escape fences, error UI, empty hint, tests
Apply the actionable feedback from the code review:
- Security: escape triple-backticks in `metadata.promptTemplate.prompt`
before interpolating it into the system prompt's fenced block. A user
who pasted ``` into the editable template body could otherwise close
the fence and inject free-form instructions for the agent. Apply the
same fix in both the contracts composer and the daemon mirror.
- UX: surface fetchPromptTemplate failures via an inline error banner
outside the popover, with a one-click retry button bound to the last
failed pick. Previously the error toast lived inside the popover and
vanished as soon as the popover closed.
- UX: show a subtle hint below the prompt textarea when the body is
empty, so users who clear it on purpose understand the agent will
have no template reference.
- Defense in depth: gate the `**referenceTemplate**:` metadata bullet
on a non-empty prompt body in both composers, so a stale title can
never appear in the system prompt without the body it claims to
reference.
- Tests: add tests/system-prompt-template.test.ts covering the happy
path (image + video), the backtick escape, the truncation cap, the
empty-prompt skip, the non-media kinds, and the missing-source path.
- i18n: add `promptTemplates.retry` and `newproj.promptTemplateBodyEmpty`
across all 9 locales; backfill the prompt-template picker keys for
ja, es-ES, de which landed on main after this branch.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Add white-space: nowrap to .viewer-action, .viewer-toggle, and .viewer-tab
to prevent Chinese/Japanese text from breaking to a new line when the
toolbar runs out of horizontal space. English text was unaffected because
browsers treat whole words as atomic units, but CJK characters can break
between any two characters by default.
Closes#141.
When the user clicked the Fullscreen button, requestFullscreen() put the
stage element into native browser fullscreen and React's `fullscreen`
state was set true. Pressing Esc was meant to exit the overlay, but in
browsers like Firefox the browser consumes Esc to drop its native
fullscreen element without delivering keydown to JS. The React state
stayed true, the `ds-modal-fullscreen` class lingered, and only a second
Esc reached the keydown handler that flipped the state.
Subscribe to `fullscreenchange` so the React state mirrors the native
state. When the browser exits its fullscreen element, the overlay drops
on the same keystroke. The keydown handler is still needed for the
fallback path (no native fullscreen API support, where requestFullscreen
is undefined and only React state is set).
Adds three regression tests in e2e/tests/preview-modal-fullscreen.test.tsx
covering the bug fix path, the keydown fallback, and a non-collapse
guard for transitions where another element is still fullscreen.
Co-authored-by: d 🔹 <258577966+voidborne-d@users.noreply.github.com>
tools-dev generated a temp web tsconfig with Windows backslash relative paths in extends, which Next/TypeScript failed to resolve in some environments. Normalize runtime tsconfig/dist path strings to POSIX separators so dev config resolution works consistently across Windows/Linux/macOS.
* 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.
The settings modal had no max-height constraint, causing its content
to exceed the viewport height with no way to scroll. The footer action
buttons (Cancel / Save) were pushed out of view and unreachable.
- Add max-height: calc(100vh - 64px) to .modal-settings
- Wrap settings sections in .modal-body (flex: 1, overflow-y: auto,
min-height: 0) to create a scrollable content area
- Pin .modal-head and .modal-foot with flex-shrink: 0 so they remain
always visible regardless of content height
Co-authored-by: jiangding001 <jiangding001@ke.com>
Co-authored-by: mrcfps <mrc@powerformer.com>