mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
a019bcd5ccf1a6f7a181a8f518b1654ce248fb0b
572
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a019bcd5cc |
fix(web): backport release-only fixes to main ahead of v0.10.0 re-cut (batch 1) (#3711)
* fix(web): avoid duplicate style picker group keys (cherry picked from commit |
||
|
|
8f6cdaaba1 |
Harden release-beta-s self-hosted beta lane (#3641)
* Fix Windows smoke launcher payload layout
* Harden release-beta-s runner probe
* Use cmd shell for release-beta-s probe
* Add win beta build script for self-hosted lane
* Keep release-beta-s checkout lightweight
* Use explicit local beta version for release-beta-s
* Install dependencies in beta build script
* Repair Electron dist before Windows beta build
* Add release-beta-s timings and diagnostics
* Polish release-beta-s observability guardrails
* Trace tools-pack cache materialization
* Reuse materialized workspace build cache
* Trace Windows packaging segments
* Trace Windows archive process details
* Reuse installer unpacked materialization
* Preserve reusable Windows unpacked projection
* Add fast smoke telemetry for self-hosted beta
* Cache Windows archive outputs for beta lane
* Tighten fast Windows smoke lane
* Scope Windows beta artifact reporting by target
* Clean stale Windows target artifacts
* Wire Windows Authenticode signing
* Expose self-hosted beta validation modes
* Add core Windows smoke profile
* Decouple core smoke from updater fixture version
* Trace Windows smoke lifecycle steps
* Skip unpacked materialization on NSIS cache hit
* Add Nexu S3 beta publisher
* Harden self-hosted Windows beta lane
* Use Windows PowerShell for publish probe
* Run publish probe via repo script
* Require explicit self-hosted S3 public origin
* Run real installer acceptance for external feeds
* Skip ready-prompt checks for external feeds
* Relax optional self-hosted update inputs
* Tolerate BOM in self-hosted publish probe
* Converge self-hosted beta metadata and signing flow
* Run self-hosted beta metadata prep on the runner lane
* Use Windows PowerShell for self-hosted beta metadata checks
* Bypass execution policy in self-hosted beta metadata checks
* Split self-hosted beta metadata publish
* Suppress mc output in beta publish helpers
* Split Windows NSIS payload cache layers
* Require fresh tool dist metadata
* Preserve Windows overlay payload paths
* Default beta-s gate to core
* Optimize win beta packaging reuse
* simplify windows full smoke lifecycle
* preserve onboarding state after windows upgrade smoke
* fix windows tools-pack test portability
* recover stale tools-pack locks
* Allow auto signing fallback for beta builds
* Add self-hosted beta mac arm64 lane
* Quote self-hosted signing choices
* Run self-hosted beta metadata on mac lane
* Use shallow metadata checkout on self-hosted beta
* Use sparse beta metadata checkout
* Make mac release profile bash-compatible
* Allow file sparse metadata checkout
* Isolate self-hosted metadata checkout
* Clear sparse skip-worktree before mac build
* Isolate self-hosted mac build checkout
* Run self-hosted beta publish without aws cli
* Use unsigned beta prefix for mixed platform publish
* Sparse checkout self-hosted beta publish
* Publish mac beta platform before metadata
* Pass mac publish release profile
* Probe mac signing keychain import
* Expand mac signing preflight variants
* Use sudo keychain helper for self-hosted mac signing
* Route self-hosted mac codesign through sudo wrapper
* Normalize mac signing identity name
* Harden self-hosted mac notarization
* Optimize self-hosted mac release cache
* Fix mac signing helper cleanup
* Retry transient mac notarization uploads
* Keep mac notarization fail-fast
* Reduce mac symlink diagnostics noise
* Normalize self-hosted beta platform inputs
* chore: bump beta base version to 0.9.1
* chore: tune release tools-pack cache retention
* test: add temporary cache validation marker
* chore: key windows nsis base payload by content
* Revert "test: add temporary cache validation marker"
This reverts commit
|
||
|
|
475b9a480b |
fix(daemon): include user toolchain dirs in agent spawn PATH so shebang interpreters resolve (#3675)
What: `applyAgentLaunchEnv` now appends the user toolchain bin dirs
(Homebrew, ~/.local/bin, ~/.bun/bin, version-manager node dirs, npm
prefixes — the same set binary *resolution* searches) to the end of the
spawn PATH. Exposed via a new `userToolchainBinDirs()` from executables.ts;
injectable param defaults to the real dirs (tests pass []).
Why: agent detection resolved a binary's path using resolvePathDirs()
(PATH + wellKnownUserToolchainBins) but spawned it with a PATH containing
only nodeBinDir + the agent's own dir. An agent whose shebang interpreter
lives in a toolchain dir not on the daemon PATH then failed to execute:
Pi (`/usr/bin/env bun` via @oh-my-pi/pi-coding-agent) resolved fine but its
`--version` probe exited 127 ("env: bun: No such file or directory"), so
detection classified it not-invocable and marked Pi unavailable. claude/codex
only survived because their interpreter (node) happened to be on the spawn
PATH. Resolution and spawn PATH are now symmetric, fixing detection AND the
run/connection-test spawns that share this function.
How: append appendPathDirs into the PATH merge (lowest priority, deduped).
Verified: Pi flips unavailable -> available after the fix (path + version
now populated), alongside claude/codex.
Test: apps/daemon/tests/runtimes/launch.test.ts — "appends toolchain dirs
so shebang interpreters (e.g. bun) resolve at spawn time" (would go red
without the fix). Existing exact-PATH tests pass [] to stay deterministic.
Co-authored-by: ZC Deng <zhic.deng@gmail.com>
|
||
|
|
c6ee16be9d | feat(daemon): pass open design trace env to AMR (#3667) | ||
|
|
aa782365e0 |
feat(daemon): pass parentSession in pi RPC new_session for conversational continuity (#3434)
* feat(daemon): pass parentSession in pi RPC new_session for conversational continuity
Add parentSession option to attachPiRpcSession that sends
new_session { parentSession } before prompt on pi's stdin.
pi loads the prior .jsonl session file, forking conversation
history into the new session.
- resolveLastSessionPath(cwd) scans <cwd>/.pi/sessions/ for
the most recently modified .jsonl
- piParentSessionPaths Map in server.ts persists the last
session path per effectiveCwd
- Backward compatible — no new_session sent when no prior
session exists
- 3 new tests covering stdin ordering, backward compat, and
session path capture after agent_end
Closes #3414
* fix: replace str shorthand with string in parentSession test type annotations
* fix(daemon): scope pi session resume to conversations
* fix(daemon): handle pi parent session failures
* fix(daemon): clear stale pi session on capture miss
* fix(daemon): keep pi resume failure SSE code stable
---------
Co-authored-by: Siri-Ray <2667192167@qq.com>
|
||
|
|
aba4b5bff2 |
fix(home,daemon): keep mode card on-screen and let plugin authoring pause on a question-form (#3640)
* fix(home,daemon): keep mode card on-screen and let plugin authoring pause on a question-form Two release/v0.10.0 firefight fixes: - Home Design Agent description card: the mode toggle's popover card is only shown on the home hero and anchors upward, so at its default 360px it crowds (and on smaller windows clips) the page header. Cap its height on the home hero so it always clears the top chrome and scrolls for the overflow. - Plugin authoring 'ended before generating the required generated-plugin artifacts' error: the od-plugin-authoring turn-1 flow emits a <question-form> to collect the brief, then stops and waits for the user. That turn legitimately closes with code 0 and no artifacts yet, but the missing-artifacts guard treated it as a failure. Track whether the agent emitted a clarifying <question-form> in its streamed text and skip the guard in that case. Red spec: chat-route.test.ts 'does not fail plugin authoring when the turn-1 reply is a clarifying question-form awaiting the brief' (red on main, green on branch). * fix(daemon): recognize <ask-question> alias in plugin-authoring clarification guard The web form parser (apps/web/src/artifacts/question-form.ts) accepts both <question-form> and its <ask-question> alias as a valid brief form. The plugin-authoring missing-artifacts guard only matched the canonical tag, so a turn-1 reply using the alias still rendered a valid form in the UI but fell through to the 'ended before generating…' failure. Mirror the parser's accepted tag set in the daemon guard and add a regression test for the alias path. Addresses Looper review feedback on #3640. * fix(daemon): gate plugin-authoring clarification carve-out on a renderable form body The previous carve-out matched only the question-form/ask-question opening tag, so a malformed (non-JSON) body — which the web parser keeps as raw prose with no rendered form card — would still suppress the missing-artifacts failure, turning a hard failure into a false success. Mirror the parser's minimal renderable contract in a daemon-local helper (emittedRenderableQuestionForm): a closed question-form/ask-question block whose body parses as JSON to an object with a non-empty questions array. Buffer the run's visible text and validate at close. Documented as a deliberate mirror of apps/web/src/artifacts/question-form.ts since the app boundary forbids importing it; promote to packages/contracts if they drift. Tests: question-form and ask-question fixtures now use valid JSON bodies, plus a new regression pinning that a non-renderable (non-JSON) form body still fails. Addresses Looper review feedback on #3640. * fix(daemon): keep question-form close-tag scan Unicode-safe in the daemon mirror The mirrored renderable-form check lowercased the whole buffer before indexing the close tag. Some code points expand under toLowerCase ('İ' -> 'i̇'), shifting every offset after them, so closeIdx desynced from openEnd (original-string coordinate) and the JSON body slice was corrupted — failing a valid form when a casing-expanding char preceded it. Mirror the web parser's findCloseTag: scan char-by-char and lowercase each fixed-length candidate slice, returning an index in the original-string space. Added a daemon regression with an 'İ' preamble before a valid form. Addresses Looper review feedback on #3640. |
||
|
|
d6fe99bcdf |
Make existing project folders easier to open and iterate (#3529)
* Support opening and iterating existing project folders * Fix existing folder flow i18n strings * Stabilize AMR status sync --------- Co-authored-by: Ben Stadler <ben@thebenstadler.com> Co-authored-by: Siri-Ray <2667192167@qq.com> |
||
|
|
d0bca92646 |
fix(conversation-forking): fork from the in-memory snapshot so an unpersisted turn no longer silently fails (#3648)
"Fork from here" creates a new conversation by asking the daemon to copy the source conversation's messages up to the fork point, looked up in SQLite by `forkAfterMessageId`. When the fork point is an assistant turn whose run errored or had its connection reset before the message was written to the database (common with AMR/ACP "Connection reset by server"), that id is not in the DB. The daemon returned 404 "fork message not found", `createConversation` turned the non-OK response into `null`, and `handleForkFromMessage` threw into a quiet error state — so no new conversation opened and the user never switched into the fork. The page just flashed and stayed put. Make fork copy what the user is actually looking at: the chat "Fork" action now sends the in-memory messages slice (up to and including the fork point) as `seedMessages`, and the daemon prefers that snapshot over reading the source conversation from the DB by id. The Side Chat path (no `seedMessages`) is unchanged and still seeds from `seedFromConversationId`. Red spec: apps/daemon/tests/projects-routes.test.ts "forks from a client-supplied snapshot when the fork point was never persisted" — 404 on main, 200 on this branch. |
||
|
|
b1fd529eea |
Feat/aihubmix byok provider (#3583)
* feat(media): integrate AIHubMix as full-stack BYOK provider Add AIHubMix (https://aihubmix.com) as a BYOK provider at the same layer as SenseAudio — both a chat protocol and a media-generation provider — so users can paste one key and get chat + image + speech, with the same key auto-mirrored into media-config for the `od media` CLI path. AIHubMix is an OpenAI-wire-compatible aggregator. Its distinguishing trait is the fixed APP-Code attribution header (discount), funnelled through a single aihubmixHeaders() helper so every outbound call point (chat proxy, connection test, model discovery, media renderers, memory extractor) injects it in one place. Chat protocol layer: - Extend ApiProtocol / ConnectionTestProtocol / MemoryExtractionProvider unions. - New web provider client + dispatch; mirror across apiProtocols, config, utils, Settings/ChatComposer/HomeHero UI surfaces. - Refactor the SenseAudio tool-loop chat proxy into a shared registerByokToolChatProxy() factory; register senseaudio + aihubmix through it (senseaudio behaviour byte-preserved). connectionTest + providerModels treat aihubmix as OpenAI-shaped with APP-Code headers. Media layer: - Register provider + image (aihubmix-gpt-image-1 / -dall-e-3) and speech (aihubmix-tts-1) models; prefixed ids stay unique and map to wire names. - OpenAI-compatible renderers (/v1/images/generations, /v1/audio/speech) and chat tool executors; ENV_KEYS + media-picker allowlists updated. Note: AIHUBMIX_APP_CODE in apps/daemon/src/aihubmix.ts is an empty placeholder — fill it with the code from https://aihubmix.com/appstore to enable the discount header (the integration works without it). Tests: media-aihubmix.test.ts (wire-name mapping, APP-Code invariant, image + speech renderers) and an AIHubMix proxy-route case; verify:media-models, guard, and typecheck all green. * feat(media): source AIHubMix model lists from live catalog endpoints Chat LLM models and media image models now come from AIHubMix's live catalogue (GET /api/v1/models?type=llm | image_generation, public, returns model_id / model_name) instead of only the hand-curated static lists. Chat: the existing /api/provider/models discovery, when protocol=aihubmix, now hits the type=llm catalogue and parses the AIHubMix envelope (342 models live). The static SUGGESTED_MODELS remain as the pre-fetch default. Media image: new GET /api/media/providers/aihubmix/models endpoint proxies the type=image_generation catalogue (53 models), prefixes ids `aihubmix-` for uniqueness, and caches for 5 min with stale-on-error fallback. generateMedia synthesizes a def for any unregistered `aihubmix-*` id (like the fal-ai/* path) so every catalogue model renders through the OpenAI-compatible image endpoint. Helpers (aihubmixCatalogUrl / parseAIHubMixCatalog) + tests for url building, envelope parsing, and rendering a dynamic catalogue id. The web media pickers still read the static seed list; wiring them to the live endpoint is a follow-up UI change. * feat(web): show live AIHubMix image catalog in all media pickers Wire the AIHubMix image-generation catalogue (53 models, fetched from the new daemon endpoint) into every image-model picker. A shared hook (useAIHubMixImageModels) fetches once per session and caches; mergeAihubmixImageModels replaces the two static aihubmix seeds with the live list (and falls back to the seeds when the fetch hasn't resolved or fails, so the picker is never empty). Surfaces: - NewProjectPanel image picker — merged list passed to supportedModels('image'). - Home media composer — buildHomeMediaComposer / fieldsForSurface / normalizeHomeMediaInputs now accept an injected imageModels list; HomeView fetches and threads it through all three composer call sites. Saved/template image-model ids starting with `aihubmix-` are accepted even though they're absent from the static IMAGE_MODELS, since they render dynamically daemon-side. * feat(byok): load AIHubMix chat model list without an API key The BYOK chat model dropdown already merges live-fetched models with the static suggestions, but the fetch was gated on a non-empty API key (every provider hits /v1/models behind its key). AIHubMix's catalogue is public, so its 342-model list now loads as soon as the AIHubMix tab is selected — no key required. - Daemon /api/provider/models accepts an empty apiKey when protocol=aihubmix (baseUrl still required); providerModelsHeaders sends no Bearer when the key is blank. - Web: missingByokModelFetchFields treats apiKey as optional for aihubmix, and the auto-fetch effect skips the commit-on-blur gate for aihubmix (base URL is prefilled and there's no key to debounce), so the list populates on tab select. * feat(byok): default AIHubMix chat model to claude-opus-4-8 * feat(byok): memory model picker uses live searchable model list The Memory model picker was a plain <select> hard-wired to the 8 static SUGGESTED_MODELS. Swap it to the same SearchableModelSelect the chat picker above uses, fed by the parent's merged fetched+suggested model options (apiModelOptions). For AIHubMix that means the full live 342-model catalogue shows as a searchable dropdown (keyless), matching the chat picker; other protocols get their live /v1/models list once the chat key is set. 'Same as chat' leads the list and 'Custom…' is pinned last. * feat(byok): BYOK chat image-model picker lists live AIHubMix catalog The Settings BYOK 'image generation model' dropdown (byokImageModel, used by the chat-injected generate_image tool) listed only the 2 static aihubmix seeds. Feed it the live image catalogue (useAIHubMixImageModels) for aihubmix so it shows all ~53 models; SenseAudio keeps its static registry list. Relax the daemon's isAIHubMixImageModel to accept any aihubmix-* id (they all render via the OpenAI-compatible endpoint with prefix-strip), so a dynamically-chosen default passes validation instead of being dropped back to the seed default. * refactor(byok): share one hook for BYOK image-model pickers; wire composer The chat composer's inline 'image generation model' picker still listed only the static aihubmix seeds. Rather than re-derive the merge+filter a third time, extract useByokImageModelOptions(provider) into the shared aihubmix-image-models module (live AIHubMix catalogue for aihubmix, static registry otherwise) and use it from both the Settings image picker and the composer picker. One cached fetch feeds all sites. * feat(byok): route AIHubMix chat by model name to native protocol wire Per the AIHubMix integration guide §4.3, route the BYOK chat by model name to each family's native endpoint on the AIHubMix origin instead of forcing every model through /v1/chat/completions: claude* → Anthropic /v1/messages (x-api-key + anthropic-version) gemini*/imagen* → Gemini :streamGenerateContent (x-goog-api-key) everything else → OpenAI /v1/chat/completions (keeps the tool loop) All three carry the APP-Code attribution header. The claude/gemini routes run base chat only (no in-chat generate_image yet) — each protocol has a pluggable tool slot for a later Anthropic tool_use / Gemini functionCall adapter. The OpenAI family keeps in-chat image/speech generation. Reuse: extracted runAnthropicChatStream / runGeminiChatStream (+ payload builders) from the existing /api/proxy/{anthropic,google}/stream handlers; those routes now delegate to the same functions (behaviour preserved, 79 proxy tests green). New helpers classifyAIHubMixModel / aihubmixOriginFromBase / aihubmixAppCodeHeader in aihubmix.ts. No SDK added. Default AIHubMix chat model is now gpt-5.5 (an OpenAI-family model) so the default keeps in-chat generate_image working after routing. Tests: claude→/v1/messages and gemini→/gemini/.../streamGenerateContent routing assertions in proxy-routes.test.ts. * feat(byok): AIHubMix in-chat image/video/audio model selection + media-adapters Bring the BYOK chat media surface to parity across image, video and audio: - Composer + Settings dropdowns for image/video/speech models and TTS voice, threaded as byokVideoModel / byokSpeechModel / byokSpeechVoice. The user's explicit pick is authoritative over the LLM's tool `model` arg (regression the LLM kept overriding the composer choice). "Default" resolves to the first live-catalogue model (honest label) with the daemon const as final fallback. - New apps/daemon/src/media-adapters: injection-style capability registry + family-aware video request builder (seedance content[] array vs generic input_reference), capability shape aligned with OpenRouter /videos/models. The chat video executor now builds requests through it. - Per-family request shaping: * video: duration snapped to each family's allowed set (veo 4/6/8, sora 4/8/12, wan 5/10); i2v reference resolved to a data URL. * image: gemini/nano-banana models routed to gemini-native generateContent (the /v1/images/generations shape 400s for them); others stay OpenAI-shaped. * speech: gemini TTS via generateContent with PCM->WAV wrapping and Gemini voice fallback; others use /v1/audio/speech (mp3). * download: same-origin AIHubMix asset URLs re-send Bearer + APP-Code. - Clear, actionable errors for unsupported i2v / "params dropped" models, plus per-call submit logging (model + endpoint) for multi-model verification. - i18n keys across 19 locales for the new pickers and the neutral default label. Tests: byok-tools + media-adapters specs (85 passing); guard + daemon/web typecheck green. * feat(byok): media tool loops on claude/gemini chat + wan i2v wire + seedance resolution fix Make AIHubMix in-chat media generation work regardless of which chat model is selected, and fix two image-to-video wire-shape bugs surfaced by live testing. chat-routes: the aihubmix routeByModel divert sent claude -> Anthropic /v1/messages and gemini -> Gemini generateContent BEFORE the OpenAI tool loop, so those chat models had no generate_image/video/speech tools ("没有音频工具"). Add per-protocol tool loops inside registerByokToolChatProxy (reusing the shared executeOneTool): runAnthropicToolTurn/Chat parse tool_use content blocks + input_json_delta; runGeminiToolTurn/Chat parse functionCall parts. The shared single-pass runAnthropicChatStream/runGeminiChatStream and the direct /api/proxy/{anthropic,google}/stream routes are untouched. Factor the per-kind tool-result hint into buildToolResultContent (shared by all three protocols) and add openaiToolsToAnthropic / openaiToolsToGemini schema converters (Gemini schema sanitized to the OpenAPI subset). Gemini 3.x attaches a thoughtSignature to each functionCall part that must be echoed back verbatim or the follow-up 400s, so replay the raw functionCall part instead of reconstructing {name,args}. media-adapters: seedance accepts resolution only as a token (480p/720p/1080p), never a WxH pixel string — passing the aspect-derived 1280x720 made it 400 ("resolution ... not valid ... in i2v"). Add snapResolutionToken to normalise. Add a third request family `wan` for wan*/happyhorse*: verified against a working happyhorse-1.0-i2v call, these are DashScope/wanx-backed and use { input:{ prompt, media:[{type:first_frame,url}] }, parameters:{ resolution, duration, prompt_extend, watermark } }, NOT the flat input_reference shape we were sending. Update the i2v failure-advice message accordingly (the remaining risk is wanx needing a public image URL while we send an inline data URL; seedance accepts the inline image). Tests: anthropic+gemini in-chat tool loops (incl. thoughtSignature round-trip), snapResolutionToken, seedance token resolution, and the wan input.media shape. * feat(byok): add veo video family + default to seedance-2.0-fast veo* models go through the gateway's OpenAI→Gemini predictLongRunning shim, which wants `seconds` as a NUMBER and only honours `size` (no aspect_ratio) — distinct enough from the generic flat shape to warrant its own `veo` family in the media-adapters builder. Verified against a working veo-3.1-lite call. Also default the BYOK chat video model to doubao-seedance-2-0-fast-260128 (the broadly-available fast i2v/t2v path) and extend the media-adapters tests to cover the veo family routing + duration snapping (4/6/8). * feat(byok): hide account-source model labels for AIHubMix AIHubMix's live model fetch returns its full account catalogue, so every picker option carried an identical "from your account" badge that added noise without distinguishing anything. Introduce a reusable ACCOUNT_MODEL_SOURCE_LABEL_HIDDEN set + hidesAccountModelSourceLabel() predicate: for listed protocols the per-option source label is dropped and the loaded-models hint shows a plain count (new settings.modelsLoadedCount key) instead of the account wording. Other providers are unaffected; add a protocol to the set to opt it in. * fix(byok): close AIHubMix catalogue SSRF + share gemini image branch Two review fixes on the AIHubMix BYOK provider: - SSRF: the public `/api/media/providers/aihubmix/models` GET took a caller-controlled `baseUrl` and fetched it server-side, so `?baseUrl=http://169.254.169.254/` could reach a private/metadata host. The catalogue lives at one fixed origin, so the route now ignores any `baseUrl` query and hard-codes the official AIHubMix origin — no attacker-chooseable fetch target remains. A focused route test asserts a malicious `baseUrl` is ignored and only aihubmix.com is contacted. - Gemini image parity: the media renderer always sent AIHubMix image models to the OpenAI `/images/generations` endpoint, which 400s for gemini/imagen-family models. Extract the chat tool's Gemini-native branch into a shared `aihubmixGeminiImageBytes` helper and route those models through it from both the chat tool and the Home/New Project/CLI media path, so the catalogue the picker exposes is fully renderable. Added a media-path test that asserts a gemini-family id hits the generateContent wire. * feat(byok): hide redundant gateway preset for single-origin AIHubMix The "gateway preset" dropdown only ever offered AIHubMix itself (plus the generic custom-endpoint option) because AIHubMix is a fixed-origin gateway with exactly one preset — redundant UI. Gate it behind a reusable GATEWAY_PRESET_HIDDEN set + hidesGatewayPreset() predicate (mirroring the existing ACCOUNT_MODEL_SOURCE_LABEL_HIDDEN pattern) so another single-origin gateway can opt in by adding its protocol, rather than hardcoding a check. The Base URL field still shows the resolved origin; multi-preset and custom-endpoint-reliant protocols (azure/google/senseaudio) are unaffected. * feat(byok): hide Base URL field too for fixed-origin AIHubMix gateway AIHubMix resolves its Base URL automatically, so the editable field was as redundant as the gateway preset. Generalize the just-added GATEWAY_PRESET_HIDDEN into one semantic concept — FIXED_ORIGIN_GATEWAYS + isFixedOriginGateway() — and drive BOTH the preset dropdown and the Base URL field off that single predicate. Adding a fixed-origin gateway protocol now hides both surfaces in one place; the user only supplies an API key. azure/google/senseaudio are unaffected. * fix(byok): close AIHubMix asset-download SSRF redirect bypass The AIHubMix asset downloads validated the literal URL via assertExternalAssetUrl but then fetched with the default redirect:'follow', so a validated public URL could 302 the daemon into 169.254.169.254 / RFC1918 space (and leak Bearer/APP-Code to the hop target). Add a shared assertAndFetchExternalAsset(url, init) helper that validates and pins redirect:'error', and route every external asset download through it: chat video/image (byok-tools.ts) and media image/video + SenseAudio image (media.ts). Also add the missing isLocalSameOrigin guard to the AIHubMix catalogue route so it matches its sibling media routes. Regression tests lock the invariant: helper-level (blocks literal metadata host, forces redirect:'error') plus chat video/image executors asserting the download fetch carries redirect:'error', and a cross-origin rejection test on the catalogue route. Also point the AIHubMix API-key console link at the referral URL. * feat(byok): carry New Project media-model pick into BYOK conversation The model chosen in New Project → Media was stored on project.metadata but dropped for BYOK providers (AIHubMix): media is produced by the generate_* chat tools whose default comes from the per-request byok*Model field, which ProjectView only seeded from Settings. Seed those overrides from the project's creation-time pick instead, gated to the active BYOK provider so a cross-provider model (e.g. a SenseAudio run whose image project defaulted to gpt-image-2) can't clobber the user's Settings default. mediaModelProviderId resolves AIHubMix's `aihubmix-` live ids by prefix so the seed survives before the async catalogue loads. * refactor(byok): remove in-chat media model selector pending unified picker Drop the in-conversation BYOK image/video/speech model dropdowns from the chat composer. Media model selection now comes from the project's creation-time pick (seeded into the byok*Model overrides), and a unified selection surface will replace this later. Also removes the now-dead option hooks/imports so the composer no longer fires AIHubMix catalogue fetches it doesn't render. The byok* props/handlers are retained as plumbing for the future unified picker. * fix(byok): resolve AIHubMix fixed-origin base URL so model lists load Hiding the Base URL field for the fixed-origin AIHubMix gateway left config.baseUrl empty, which blocked the live model-list fetch (it gates on a valid base URL) so the Settings dropdown and the top-bar switcher showed only the static suggested models. Centralise the fixed-origin concept in state/apiProtocols (FIXED_ORIGIN_GATEWAYS / isFixedOriginGateway / resolveFixedOriginBaseUrl) and resolve the canonical origin in loadConfig so every consumer sees it — including configs already persisted with an empty baseUrl. SettingsDialog now imports the shared helpers instead of redefining them. |
||
|
|
0e6d3176ab |
fix(web): prompt injection warning chip + subdirectory files and tab state (#2804)
* fix(web): show subdirectory files in root list and preserve design-files nav state across tabs Two related bugs in DesignFilesPanel: 1. Since directory navigation was added (#2442), files nested in subdirectories were excluded from the root-level flat list, making the page-size select appear broken — changing it could not surface files the user knew existed. Fix: at the root level (currentDir === ''), include all files in filesAtCurrentDir so pagination covers the whole project. Subdirectory rows still render as navigation shortcuts. 2. Switching to any other tab unmounted DesignFilesPanel, resetting kindFilter, currentDir, page, and pageSize back to defaults on return. Fix: FileWorkspace persists the four nav-state fields in a ref and passes them as initial values (navState prop) plus a change callback (onNavStateChange) to DesignFilesPanel. The ref resets when projectId changes, matching the existing key={projectId} remount behaviour. Adds a regression test for case 1. * feat(web): add possiblePromptInjection i18n key to all locales * feat(web): add injection variant CSS for system-reminder chip * test(web): add failing tests for prompt injection chip * test(web): fix null safety and strengthen assertions in injection chip tests * fix(web): render model-echoed system-reminder as prompt injection warning chip Add alert-triangle to Icon, update SystemReminderBlock to accept a variant prop (trusted|injection), render injection variant with amber warning styling and "Possible prompt injection" label, and fix the expand test to wrap click in act() for React 18 batching. * chore(web): document SystemReminderBlock variant semantics * fix(daemon): prepend prompt injection resistance block to every agent system prompt * fix(web): preserve page number across tab switches in DesignFilesPanel Three useEffect hooks that reset page to 0 (on pageSize, kindFilter, and currentDir changes) also fired on initial mount, overwriting the page restored from navState. Added a skipPageResetOnMount ref — true during the first render, set to false by an effect declared after the reset effects — so user-initiated changes still reset the page while navState is honoured on remount. Adds a regression test: navigate to page 2, unmount, remount with the captured navState, assert page 2 is restored. * fix(web): translate possiblePromptInjection key into all 17 non-English locales Replaces the English placeholder 'Possible prompt injection' with localized strings so the warning chip label is readable for non-English users. * fix(web): reset design files nav before project switch render * fix(web): restore prompt injection warning styling --------- Co-authored-by: Siri-Ray <2667192167@qq.com> |
||
|
|
2e23bafb2b | Implement Langfuse phase 2 telemetry (#3616) | ||
|
|
7403dc681e |
refactor: move daemon routes into routes dir (#3568)
* refactor: move daemon routes into routes dir * fix: restore components typecheck dependencies * fix: update host tools route test import Generated-By: looper 0.9.4 (runner=fixer, agent=codex) * fix: restore review follow-up patches * fix: tighten daemon route typing --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
e77c739e4e |
feat(daemon): resume Claude CLI sessions across turns (+ skip unchanged instruction block) (#3448)
* feat(daemon): add agent_sessions store for per-conversation CLI session ids * refactor(daemon): align getAgentSession row cast with DbRow convention * feat(daemon): claude adapter emits --resume/--session-id from runtime context * feat(daemon): add resolveAgentResumeContext resume/create decision helper * feat(daemon): detect claude --resume missing-session failures * feat(daemon): resume Claude CLI session across conversation turns * fix(daemon): persist claude session id after spawn-budget guards * feat(daemon): store stable instruction hash on agent_sessions * feat(daemon): carry stored stable-instruction hash in resume context * feat(daemon): skip unchanged stable instructions on Claude resume turns * refactor(daemon): extract computeIncludeStable with unit tests; harden agent_sessions ALTER guard * fix(daemon): persist Claude session after successful turn --------- Co-authored-by: Siri-Ray <2667192167@qq.com> |
||
|
|
ccc165f206 |
fix(daemon): don't fail a run when a post-completion SessionEnd hook exits non-zero (#3373)
* fix(daemon): don't fail a run when a post-completion SessionEnd hook exits non-zero A chat run whose model already emitted a clean terminal turn was marked failed when the spawned agent's SessionEnd hook (e.g. the Honcho memory plugin) exited non-zero during teardown, dragging the claude child to exit 1. classifyChatRunCloseStatus mapped any non-zero exit to failed, so a post-result teardown exit surfaced a red AGENT_EXECUTION_FAILED banner and halted the flow for work that had already succeeded. Add a post-completion carve-out: track turnCompletedCleanly at the exact point the daemon observes a clean terminal turn (turn_end/usage with no outstanding host answer -- the same condition that closes the child's stdin), and classify a later non-zero exit or kill signal as succeeded. Non-zero exits before a clean turn still fail, and the agent-specific auth/quota/AMR guards still run first. Fixes #3372 * fix(daemon): record clean turn after host answers --------- Co-authored-by: Siri-Ray <2667192167@qq.com> |
||
|
|
6408937564 |
feat(web): redesign Design Files panel + pick working directory from Home (#3358)
* feat(web): align Design Files panel with Claude reference UI Redesign the Design Files panel into a continuous grouped table that mirrors Claude's own Design Files surface: uppercase gray section bands (Folders / Stylesheets / Scripts / Documents / Images …), flush full-width rows with a colored icon block + bold name + type subtitle + right-aligned timestamp, a clean single-line toolbar (breadcrumbs left, New sketch / Paste / Upload right), a right preview card with a centered Open action and `Modified … · size · EXT` stats, and a static USEFUL INFO footer. Removes the old table/sort-header/kind-filter/pagination/group-toggle chrome and the conflicting legacy `.app .df-*` overrides in routines.css that were trumping the panel's own stylesheet via specificity. Preserves batch select/download/delete, rename, the row context menu, live-artifacts, plugin-folders, drag-upload, and the reloading overlay. Adds the designFiles.* section/kind/useful-info i18n keys across all locales. * feat: pick a working directory from Home before the project exists Let users choose a code folder on the Home screen up front, instead of only being able to replace it after a project is created. The HomeHero composer gains a folder pill (pick / clear); the chosen path is threaded through project creation and applied via the working-dir API once the project id exists. On desktop the working-dir POST is gated behind a host-minted token, so add a `dialog:pick-working-dir` IPC handler that shows the native picker and mints a single-use token bound to the folder, plus a `pickHostWorkingDir()` bridge + types/normalizer in `@open-design/host`. The renderer feature-detects the bridge and falls back to the web folder dialog (no token) otherwise. Native dialogs now allow creating a new folder inline (`createDirectory` / `ShowNewFolderButton`), and macOS uses `choose folder` so the panel reliably takes key focus. Wire the WorkingDirPill into the project composer footer and surface a reloading state + breadcrumb root label to the Design Files panel while a replace reindexes. Drop the WorkingDirPill "recent directories" localStorage list in favor of a single Replace action. * fix(web): preserve staged Home attachments when picking a working dir Move the working-dir handoff ahead of the initial upload so staged attachments land in the external folder instead of the temporary managed root, and fall back to the browser folder dialog when the desktop host build does not expose pickWorkingDir. * fix(web): surface host pick errors and normalize Windows dir basenames When the desktop host is present but cannot mint a working-dir token, surface the error instead of falling back to the browser folder dialog — the tokenless raw path would be rejected by the desktop auth gate as a late create-time failure. Only the pure web path (no token gate) keeps the dialog fallback. Also split the Home pill basename on both path separators so Windows paths show the folder name, not the full path. * fix(web,desktop): harden Home working-dir handoff against auth/token failures Run the desktop-auth handshake before minting the Home working-dir token so a missed startup registration fails up front instead of as a rejected deferred POST. Surface a create-time error toast when the working-dir handoff fails (expired ~60s token or daemon rejection) instead of silently leaving the project in the managed root while the user believes their folder was applied. * fix(web): abort create on failed working-dir handoff and always show root crumb When the pre-create working-dir handoff fails, short-circuit the rest of the Home submit path (skip the staged-attachment upload and auto-send) so the first run cannot proceed against the managed `.od/projects/<id>` tree the user did not choose, and reword the error toast accordingly. Always render the Design Files root breadcrumb, falling back to the `designFiles.crumbs` label when no rootDirName exists, so the toolbar is not blank on the default managed-storage view. Adds regressions for the short-circuit and default-root crumb cases. Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code) * fix(web): normalize Windows separators in WorkingDirPill basename shortPath() split only on '/', so a Windows working dir like C:\work\repo rendered as the full absolute path in the footer pill instead of the folder name. Split on both separators to match HomeHero/ProjectView, and add a regression covering the backslash path. Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code) --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
fd8159216a |
feat(design-systems): import shadcn registry items as design systems (#3525)
* feat(design-systems): import shadcn registry items as design systems Add a third design-system import source alongside local folders and public GitHub repos: a shadcn registry item, referenced with the shadcn CLI shorthand `<owner>/<repo>/<item>` (resolved against the repo's root registry.json) or a direct https URL to a registry-item document. The item's cssVars theme is materialized into a temporary project and run through the existing local importer, so a shadcn theme yields the same DESIGN.md + tokens.css + manifest.json as every other import. Classic shadcn bare-HSL cssVars (e.g. "222 47% 11%") are wrapped into hsl(...) so brand colors survive instead of falling back to neutrals. Exposed on both surfaces, per the capability dual-track rule: - POST /api/design-systems/import/shadcn, with ImportShadcn* DTOs in packages/contracts and a "shadcn" source in the design-system manifest schema. - `od design-systems import-shadcn <reference> [--name --import-mode --craft --json]`. - Settings -> Design systems: a new "shadcn" import source (placeholder shadcn/ui/theme-zinc), with i18n keys added across all locales. http:// references are accepted only for loopback hosts so a self-hosted local registry can be imported and tests stay deterministic. * fix(design-systems): harden shadcn importer per review - Fail fast in writeShadcnFiles: a declared registry file that 404s, exceeds the size cap, exceeds the file-count cap, or has no safe destination now throws a path-named LocalDesignSystemImportError instead of silently producing a partially-materialized design system. - Resolve the shadcn `include` registry layout recursively; an item's relative file paths now resolve against the registry.json that declared it (so `owner/repo/item` works for registries that use include). - Keep the fetch abort timer armed across response-body consumption so a server that stalls the body cannot hang the import. - Block SSRF: redirect:'error' on the default fetch, plus per-fetch host re-validation (https, or http only for loopback) on every URL we contact - entry point, raw GitHub URLs, include targets, and raw files. Adds regression tests for include resolution, a 404 declared file, an oversized inline file, and a non-loopback http include target. * fix(design-systems): close two shadcn importer review gaps - parseShadcnReference: wrap decodeURIComponent of the URL fragment so malformed percent-encoding (e.g. "#%E0%A4%A") surfaces as a 400 BAD_REQUEST instead of an uncaught 500 from the import route. - writeShadcnFiles: two declared files that collapse to the same sanitized destination (e.g. "@/button.tsx" + "button.tsx") now fail as a BAD_REQUEST naming both sources, instead of silently dropping the later file - the same partial-materialization failure mode this PR avoids. Adds parser + importer regression tests for both. * fix(design-systems): harden shadcn importer (SSRF, resource bounds, fidelity) A deeper hardening pass from an adversarial self-review of the importer. SSRF egress policy (assertFetchableUrl): loopback is allowed over http or https (self-hosted/local registries); private (10/8, 172.16/12, 192.168/16, 100.64/10), link-local (169.254/16, fe80::/10), ULA (fc00::/7), unspecified (0.0.0.0, ::), and IPv4-mapped/integer-encoded internal addresses are refused for BOTH schemes; any other host must be https. Enforced at parse time and on every fetch - entry point, include targets, and raw files - so a direct https://169.254.169.254, or an include/redirect pivot to an internal address, is blocked rather than only the http downgrade. Resource bounds: bodies are read with a running byte cap (no unbounded buffering) plus a Content-Length pre-check; the whole import shares one wall-clock deadline and a max-total-requests budget; include breadth and file count are capped. A stalled/huge body or a large include fan-out can no longer hang or OOM the import. Fidelity / fail-fast: a files[] entry with no usable destination is now a 400 (was silently skipped); registry files are materialized under a subdirectory so a crafted target cannot overwrite the importer's theme.css/package.json/ README.md; cssVars keys/values are validated so a hostile entry cannot inject extra declarations or be silently dropped; slashed git refs are encoded per segment; direct-URL items resolve path-only files relative to the item URL; fetch timeouts surface as a clean BAD_REQUEST. Adds tests for each: https-internal SSRF (entry + include), a no-destination file, a reserved-file overwrite attempt, a slashed ref, a direct-URL path-only file, cssVars injection, and a streaming over-cap body. |
||
|
|
33d59ebb3a |
Clarify OpenCode reasoning support and avoid unsupported reasoning argv (#3346)
* Clarify OpenCode reasoning support * Address PR review suggestions --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> |
||
|
|
836d734455 |
[codex] Add same-run retry runtime (#3576)
* Add same-run retry runtime * fix(daemon): route retried-start and watchdog stall through retry finalizer Two retryable failure paths bypassed the same-run retry finalizer, so they emitted no run_retry_attempted/run_retry_finished telemetry and could report the fallback retry_final_result: 'not_attempted'. - restartSameRunAfterRetry's catch now routes a failed retried start through finishWithRetryDecision instead of design.runs.finish, so it emits terminal retry telemetry and sets run.retryFinalResult. retryAttemptCount is already 1 there, so decideSafeRunRetry suppresses with attempt_limit_reached and cannot loop. - failForInactivity's no-output stall now routes through the finalizer after surfacing stallPayload. A silent first-token hang classifies as a retryable timeout at first_token_wait, so the same-run retry now recovers it. A new watchdogRetryRestarted guard makes the SIGTERM'd stalled child's close bail early (revoking only its own tool token) so it cannot re-finalize the run or delete the new attempt's event sink (both keyed by the shared runId). - finishWithRetryDecision returns whether it restarted so the watchdog can set the guard. Adds a run-retry-runtime test with a low OD_CHAT_RUN_INACTIVITY_TIMEOUT_MS proving the same-run retry fires for a silent first attempt. |
||
|
|
dbc74a397c |
feat(agents): CLI detection self-rescue with actionable diagnostics (#3560)
* feat(agents): surface actionable CLI diagnostics Detect unavailable CLI agents with structured diagnostics, stream agent discovery results to the settings UI, and render actionable fix controls for common setup failures. Also harden the streamed agents client so server error events and dropped streams surface as failures instead of replacing state with a truncated agent list. * fix(agents): gate streamed rescan loading Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * fix(agents): distinguish non-executable CLI diagnostics Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * fix(agents): defer OAuth diagnostics without producer Generated-By: looper 0.9.2 (runner=fixer, agent=codex) --------- Co-authored-by: chaoxiaoche <chaoxiaoche@chaoxiaochedeMacBook-Pro.local> Co-authored-by: Looper <looper@noreply.github.com> Co-authored-by: Looper Fixer <looper-fixer@noreply.github.com> Co-authored-by: looper-fixer <looper-fixer@users.noreply.github.com> |
||
|
|
f3ec4968af |
feat(web): revamp chat UI styling + live streaming code card (#3382)
* feat(web): revamp chat UI styling + live streaming code card Restyle the chat pane (chat/tokens/code/tools/routines/composio CSS) and add a live code-component card that streams Write/Edit tool input and <artifact type="text/html"> bodies character-by-character via a new ephemeral tool_input_delta SSE event, flipping to the completed FileWriteCard/FileEditCard view on close. Includes shiki highlighting, markdown/artifact strip handling, tool-status cleanup, and i18n keys. * chore(nix): refresh pnpm deps hash for merged lock --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
90aab29695 |
feat(analytics): attribute AMR entry conversions (#3579)
* feat(analytics): attribute AMR entry conversions
* test(web): cover AMR attribution entry points
* fix(daemon): gate AMR entry mirror on analytics consent
The /api/integrations/vela/analytics-entry route forwarded every AMR
entry click to the external AMR ingest endpoint regardless of consent:
mirrorAmrEntryAnalytics fired whenever globalThis.fetch existed, so an
opted-out user's click was still shipped to a third-party service.
Gate the mirror the same way the analytics-capture path does:
- null readAnalyticsContext (no x-od-analytics-* headers => Privacy
metrics off) short-circuits to { mirrored: false }.
- defense-in-depth re-read of telemetry.metrics from app-config drops
the mirror even if a stale header leak slips through after opt-out.
Adds two daemon route red specs asserting that a no-headers request and
a metrics-off request never hit the capture server.
---------
Co-authored-by: lefarcen <935902669@qq.com>
|
||
|
|
c6722d2671 |
feat: Lexical composer, interactive terminals, comment attachments & browser reference board (#3516)
* feat(daemon): add interactive terminal support with node-pty - Introduced a new terminal service to manage interactive terminal sessions. - Added routes for creating, streaming, and managing terminal sessions in the daemon. - Integrated terminal functionality into the CLI, allowing users to open interactive shells. - Updated project routes to support conversation seeding for side chats. - Enhanced the web application to include terminal tab functionality and UI components. This feature enables users to interact with a terminal directly within the application, enhancing the overall user experience and providing a more integrated development environment. * feat(web): implement embedded browser module in Design Files workspace - Added a `+` icon to the Design Files tab for opening a new Browser module. - The Browser module supports navigation features including back, forward, refresh, and address input. - Integrated a curated list of design reference URLs for user convenience. - Implemented browser data clearing functionality via IPC. - Enhanced desktop runtime to support embedded browser with appropriate security measures. - Added tests for browser functionality and URL handling. This commit establishes a new workspace for browsing and referencing design resources directly within the application, improving user experience and accessibility to design tools. * refactor(web): enhance add tab menu functionality in FileWorkspace - Updated the add tab button to toggle the visibility of the menu with improved accessibility attributes. - Refactored the add menu to be portaled to the document body for better positioning and visibility. - Adjusted CSS styles for the add menu to use fixed positioning and increased z-index for proper layering. - Minor CSS adjustments in entry layout for consistent padding. These changes improve the user experience when adding new modules in the FileWorkspace, ensuring the add menu is more accessible and visually consistent. * feat(daemon): introduce session mode for conversations - Added a new `session_mode` column to the `conversations` table with a default value of 'design'. - Implemented logic to handle `session_mode` in conversation creation, updates, and retrieval. - Enhanced the API to support `session_mode` in conversation requests, allowing for 'chat' or 'design' modes. - Updated the web application to include a session mode toggle, enabling users to switch between chat and design modes seamlessly. - Adjusted system prompts to reflect the current session mode, providing context-aware responses. This feature enhances the user experience by allowing for more flexible conversation management, catering to different interaction styles. * feat(web): enhance navigation and settings functionality in DesignBrowserPanel and EntryShell - Introduced a navigation stack in DesignBrowserPanel to manage back and forward navigation states. - Updated the browser navigation logic to handle URL history and improve user experience. - Added a settings menu in EntryShell for quick access to language and appearance options. - Implemented CSS styles for the new settings menu, ensuring a consistent and user-friendly interface. - Enhanced tests for navigation functionality and settings menu interactions. These changes improve the overall usability of the application by streamlining navigation and providing easy access to settings. * feat(daemon): enhance conversation session mode handling - Added a new `mode` flag to CLI commands for project and conversation creation, allowing users to specify 'design' or 'chat' modes. - Implemented `normalizeChatSessionModeFlag` function to validate and normalize session mode inputs. - Updated project routes to handle session mode during conversation creation and updates. - Enhanced web components to support session mode changes, including new props and handlers for managing session modes in conversations. - Adjusted UI elements to reflect the current session mode, improving user experience and interaction flexibility. This update provides a more robust framework for managing conversation modes, catering to diverse user needs and enhancing overall functionality. * feat(web): enhance HandoffButton and DesignBrowserPanel with improved functionality and styling - Updated HandoffButton to support framework-specific CLI prompts and improved local project path handling. - Enhanced DesignBrowserPanel to manage browser history with favicon support and improved address display. - Introduced new utility functions for formatting addresses and extracting hostnames. - Refactored CSS styles for better layout and responsiveness across components. - Added tests for new functionalities in HandoffButton and DesignBrowserPanel, ensuring robust behavior. These changes improve user experience by streamlining the handoff process and enhancing the design browsing capabilities within the application. * feat(web): enhance HandoffButton and ProjectView with improved instructions handling and UI updates - Updated HandoffButton to include a tabbed interface for switching between editor and CLI options, enhancing user experience. - Added support for opening the AMR website directly from the HandoffButton. - Refactored ProjectView to implement a modal for custom instructions, allowing users to edit and review instructions more intuitively. - Improved CSS styles for project instructions modal and handoff menu, ensuring better layout and responsiveness. - Added keyboard accessibility for closing the instructions modal with the Escape key. These changes streamline the handoff process and improve the usability of custom instructions within the application. * feat(daemon): add social share functionality and project folder management - Introduced new `share` command in CLI for building localized social-share targets for Open Design projects. - Implemented `printShareUsage` and `runShare` functions to handle share requests and display usage instructions. - Added API routes for social sharing, allowing users to create shareable links for projects. - Enhanced project routes with new endpoints for listing and creating project folders, improving project organization. - Updated relevant files and tests to support new functionalities, ensuring robust behavior. These changes enhance user experience by facilitating social sharing and better project management within the application. * feat(web): enhance DesignBrowserPanel and DesignFilesPanel with improved address formatting and drag-and-drop functionality - Refactored `formatAddressDisplay` to utilize a new `formatAddressDisplayParts` function, separating URL and title handling for better clarity. - Updated `DesignFilesPanel` to improve drag-and-drop interactions, including enhanced directory navigation and file management features. - Adjusted CSS styles for better visual consistency and responsiveness across components. - Added tests for new functionalities in `DesignBrowserPanel` and `DesignFilesPanel`, ensuring robust behavior. These changes improve user experience by streamlining address formatting and enhancing file management capabilities within the application. * feat(web): enhance DesignBrowserPanel and DesignFilesPanel with new reference categories and improved folder creation - Added new reference categories in DesignBrowserPanel, including 'Inspiration', 'Real Interfaces', 'Color', 'Typography', and more, each with curated design resources. - Improved folder creation logic in DesignFilesPanel to suggest names based on existing folders, enhancing user experience. - Updated CSS styles for better layout and responsiveness across components, particularly in control rows and search functionalities. - Added tests for new reference categories and folder creation features, ensuring robust functionality. These changes enrich the design resource catalog and streamline folder management, improving overall usability within the application. * feat(web): implement reference icon functionality and enhance social share features - Replaced favicon URL generation with a new `referenceIconUrl` function to provide reliable icons for curated design sites, improving visual consistency in the DesignBrowserPanel. - Updated the FileViewer component to enhance social share functionality, including clearer messaging for protected deployments and improved UI for sharing links. - Added CSS styles to support new visual states for social share components, ensuring better user experience. - Expanded tests for the new `referenceIconUrl` function and social share interactions, ensuring robust functionality. These changes enhance the design resource presentation and improve the sharing experience within the application. * feat(web): enhance DesignFilesPanel and FileViewer with improved folder management and social share functionality - Added optimistic folder path management in DesignFilesPanel to improve user experience during folder creation. - Updated social share logic in FileViewer to handle protected deployments more effectively, ensuring clearer messaging and UI updates. - Refactored CSS styles for better layout and responsiveness in both components, enhancing overall usability. - Expanded tests for new folder management features and social share interactions, ensuring robust functionality. These changes streamline folder management and enhance the social sharing experience within the application. * feat(daemon): enhance project tab management with new state handling - Updated database schema to include a new `state_json` column in the `tabs_state` table for improved project tab state management. - Implemented functions to normalize and parse project tab states, including handling browser workspace tabs. - Modified `listTabs` and `setTabs` functions to utilize the new state management features, allowing for better tracking of active tabs and saved states. - Refactored related types in the contracts and web applications to support the new tab state structure. These changes improve the functionality and user experience of managing project tabs within the application. * feat(web): enhance project tab management and browser tab functionality - Updated project routes and server logic to include `browserTabs` in the request body, improving tab state management. - Implemented validation for `browserTabs` to ensure it is an array, enhancing error handling. - Refactored `setTabs` function to accommodate the new structure for managing tabs, including browser-specific tabs. - Added tests for browser tab state persistence and management in the new `project-tabs-state.test.ts` file, ensuring robust functionality. These changes improve the user experience by providing better management and persistence of project and browser tabs within the application. * feat(web): enhance ProjectView with improved chat send management and UI updates - Added support for queue-only chat sends, allowing for better handling of messages during busy conversations. - Refactored chat send functions to improve state management and persistence of queued messages. - Updated CSS styles in the DesignFilesPanel for better layout and responsiveness, including search control enhancements. - Expanded tests for new chat send functionalities and search interactions, ensuring robust behavior. These changes improve the user experience by streamlining chat interactions and enhancing the overall design file management interface. * feat(web): improve project tab state management and caching - Enhanced the `loadTabs` function to utilize cached tab states, improving performance and user experience during data fetching. - Implemented `normalizeTabsState` and caching functions to manage tab states effectively, including validation and error handling. - Updated `writeCachedTabs` to ensure the latest state is stored in local storage, facilitating better persistence of tab information. - Modified `listTabs` in the daemon to include `updatedAt` in the state retrieval, allowing for more accurate tracking of tab updates. These changes streamline tab management and enhance the overall responsiveness of the application. * feat(web): integrate Lexical for enhanced text composition and mention handling - Added Lexical as a dependency to improve text composition capabilities within the chat interface. - Implemented mention functionality with the creation of `MentionNode` and related serialization/deserialization logic for inline mentions. - Enhanced `ChatComposer` and `ChatPane` components to support queue-only message sending and improved state management for queued messages. - Updated `DesignBrowserPanel` and `PreviewDrawOverlay` to incorporate new features for capturing and annotating browser snapshots. - Refactored various components to streamline interactions and improve user experience during chat and design tasks. These changes significantly enhance the text editing experience and provide better management of chat interactions, improving overall usability in the application. * feat(workspace): integrate terminal viewer and enhance chat functionality - Added a new terminal viewer component with customizable themes and improved styling for better user experience. - Integrated terminal functionality into the workspace, allowing users to interact with a terminal directly within the application. - Updated chat components to support active conversation states, enabling seamless message handling and interaction. - Refactored chat-related props and state management to enhance performance and maintainability. - Removed deprecated file tree explorer components to streamline the workspace interface. This update enhances the overall functionality of the workspace, providing users with a more integrated and responsive environment for both terminal and chat interactions. * feat(workspace): enhance chat and session mode functionality - Introduced a new `+` launcher in the workspace for easy access to project files and new tabs, including Side Chat and Terminal. - Added Side Chat functionality that allows users to create context-aware conversations based on existing chats. - Implemented a new terminal tab type for interactive terminal sessions using `node-pty`, enabling users to run shell commands directly within the workspace. - Enhanced chat functionality with a new session mode toggle, allowing users to switch between 'design' and 'chat' modes seamlessly. - Added a feature to copy chat responses as markdown to the clipboard, improving usability and sharing capabilities. - Updated various components and styles to support these new features, ensuring a cohesive user experience. This update significantly improves the workspace's interactivity and usability, providing users with more tools for collaboration and development. * feat(workspace): enhance session mode toggle and chat functionality - Improved the SessionModeToggle component to include localized guidance cards that provide context-aware descriptions for each mode. - Updated the UI to display a popover with mode descriptions when hovering over options, enhancing user understanding of the available modes. - Added a new copy button in the AssistantMessage footer to allow users to copy responses as raw Markdown, improving usability for external documentation. - Enhanced localization support by updating i18n keys and translations for various languages, ensuring consistent user experience across different locales. - Refactored styles for the session mode toggle and associated components to improve layout and responsiveness. This update significantly enhances the user experience by providing clearer guidance and improved functionality in chat interactions. * feat(styles): enhance session mode toggle styling for improved visibility - Added new CSS rules to ensure the session mode toggle popover and hover cards are displayed correctly with increased z-index and visibility. - Updated styles for various chat components to maintain consistent positioning and overflow behavior when session mode elements are present. - Improved overall layout responsiveness for chat interactions, enhancing user experience during mode transitions. This update refines the visual presentation of session mode toggles, ensuring they are more accessible and user-friendly. * feat(web): finish Lexical composer input with atomic mention pills * fix(web): make browser reference board scroll with a pinned toolbar The browser tab's default Reference Board (.db-start) is wrapped by PreviewDrawOverlay's position:absolute container, which is not a flex parent — so .db-start's flex:1 1 auto never bounded its height and the board grew to its content height instead of scrolling (and the sticky .db-reference-toolbar could not pin). Fill the overlay with height:100% like the .db-webview/.db-fallback siblings already do, restoring scroll and the sticky toolbar. * test(daemon): expect updatedAt in persisted tab state round-trip listTabs() returns the tabs_state row's updatedAt timestamp on the saved-state path, but these two toEqual assertions predated that field and failed strictly. Match the real shape with expect.any(Number). * feat(chat): enhance ChatComposer with session mode management and UI improvements - Introduced a new `sessionMode` prop to the ChatComposer, allowing users to switch between different session modes (e.g., 'design'). - Added a SessionModeToggle component for improved user interaction and visibility of session options. - Updated the ToolsTab type to reflect the removal of the pet option, streamlining the tools available in the composer. - Refactored styles to enhance the visibility and positioning of session mode elements, ensuring a better user experience during mode transitions. - Improved the handling of draft state and user interactions within the composer, enhancing overall functionality. These changes significantly improve the ChatComposer's usability and flexibility, providing users with clearer options and a more responsive interface. * feat(chat): implement caret floating layer for mention and slash popovers - Introduced a new `CaretFloatingLayer` component to manage the positioning of mention and slash command popovers relative to the caret. - Enhanced `ChatComposer` to utilize the caret rectangle for accurate popover placement, improving user experience during text input. - Updated `LexicalComposerInput` to pass caret position data to the trigger handling logic, allowing for dynamic popover adjustments. - Refactored styles for popovers to ensure consistent appearance and behavior, including improved animations and responsiveness. - Added accessibility features to mention and slash popovers, enhancing usability for keyboard navigation. These changes significantly improve the interaction model for mentions and commands within the chat interface, providing a more intuitive and responsive user experience. * feat(chat): update mention tab order and improve search functionality - Reordered the mention tab sections in the ChatComposer to prioritize 'Design files' over other categories, enhancing user experience during mentions. - Updated the search prompt to reflect the new tab order, ensuring clarity in search functionality. - Enhanced the mention selection logic to accommodate the new tab structure, allowing for a more intuitive navigation experience. - Added tests to verify the correct display and functionality of the updated mention tabs and search behavior. These changes significantly improve the usability of the mention feature within the chat interface, making it easier for users to find and select relevant items. * feat(chat): enhance context management in ChatComposer and HomeHero - Added functionality to manage MCP servers and connectors within the ChatComposer, allowing users to remove these contexts seamlessly. - Updated the HomeHero component to support the selection and removal of MCP servers and connectors, improving context handling in user interactions. - Enhanced the search prompt to include files, ensuring users can search across all relevant categories. - Refactored related components and styles for better integration and user experience. - Added tests to verify the correct functionality of the new context management features. These changes significantly improve the usability of context features in the chat interface, making it easier for users to manage their interactions effectively. * feat(chat): enhance message handling with session mode and plugin snapshot support - Added new columns to the database schema for `session_mode` and `applied_plugin_snapshot_json` to support enhanced message context. - Updated the `upsertMessage` and `listMessages` functions to handle the new fields, ensuring messages can store and retrieve session mode and plugin snapshot data. - Enhanced the `ChatComposer` to manage and send the applied plugin snapshot as part of the message context, improving user interaction with plugins. - Introduced a new `MessageSessionModeChip` component to visually represent the session mode in the chat interface. - Updated styles for better presentation of session mode and plugin context within messages, enhancing user experience. These changes significantly improve the context management capabilities in the chat interface, allowing for richer interactions and better tracking of session-specific data. * feat(chat): add annotation handling and UI improvements in ChatComposer and PreviewDrawOverlay - Implemented functionality to stage draw annotations into the composer input without sending, enhancing user interaction. - Added a new button in the PreviewDrawOverlay to allow users to append notes to the input, improving workflow flexibility. - Updated the ChatComposer tests to verify the correct staging of annotations and their integration into the input. - Enhanced internationalization support by adding new translation keys for annotation actions across multiple languages. These changes significantly improve the user experience by providing more intuitive annotation handling and better integration within the chat interface. * feat(capture): implement page capture functionality and enhance folder management dialogs - Added new capture functionality to allow users to take snapshots of the current page, improving user interaction with visual content. - Introduced in-app dialogs for folder creation and moving files, replacing the unsupported window.prompt in the Electron desktop host, enhancing usability across platforms. - Updated the DesignFilesPanel to support these new dialogs, ensuring a seamless experience for managing project files. - Enhanced internationalization support by adding new translation keys for folder management actions across multiple languages. These changes significantly improve the user experience by providing intuitive capture options and streamlined file management within the application. * feat(projects): implement folder deletion and enhance project file management - Added a new API endpoint to delete project folders, improving the file management capabilities within the application. - Introduced utility functions for ensuring project subdirectories and safely deleting folders, enhancing the robustness of folder operations. - Updated the DesignFilesPanel and FileWorkspace components to support folder deletion actions, providing users with a more intuitive interface for managing project files. - Enhanced internationalization support by adding new translation keys for folder management actions. These changes significantly improve the user experience by streamlining folder management and providing clearer options for users to organize their projects effectively. * feat(composer): enhance BoardComposerPopover with image attachment functionality - Added support for attaching images to comments, allowing users to upload and preview images directly within the composer. - Implemented new handlers for image input changes and clipboard pasting, improving the user experience for image uploads. - Updated the component's props to include image-related callbacks and state management for attached images. - Enhanced styles for image thumbnails and removal buttons, ensuring a cohesive design with the existing comment popover interface. These changes significantly improve the functionality of the BoardComposerPopover, providing users with a more interactive and visually rich commenting experience. * feat(file-viewer): enhance comment attachment functionality with image support - Updated the `onSendBoardCommentAttachments` prop to accept an additional `images` parameter, allowing for image attachments alongside comments. - Introduced state management for handling attached images, including functions to add and remove images, and to generate previews. - Implemented a modal for previewing attached images, improving user interaction when managing comment attachments. - Updated the `FileWorkspace` component to reflect changes in the props, ensuring consistency across components. These enhancements significantly improve the commenting experience by enabling users to attach and preview images directly within the file viewer. * feat(home-hero, project-view, styles): enhance functionality and user experience - Updated the HomeHero component to prevent unnecessary state changes during programmatic updates, improving user interaction with prompts. - Enhanced the ProjectView component to support image attachments alongside comments, allowing for a more versatile commenting experience. - Implemented a new image upload process that queues tasks efficiently, ensuring smooth handling of comment attachments. - Added CSS to reserve scrollbar space in design files, preventing layout shifts when scrollbars appear, thus enhancing visual stability. These changes collectively improve the user experience by streamlining interactions and ensuring consistent UI behavior across components. * feat(preview-comments, chat): enhance comment functionality with attachment support - Added support for `attachments_json` in the `preview_comments` table, allowing users to attach files to comments. - Updated relevant functions to handle attachments, including `upsertPreviewComment` and `listPreviewComments`, ensuring attachments are properly managed and displayed. - Enhanced the `CommentSidePanel` to render attached files, providing users with a visual representation of their attachments. - Improved the `BoardComposerPopover` and `ChatPane` components to support image attachments, including drag-and-drop functionality for reordering queued sends. These changes significantly enhance the commenting experience by enabling users to attach and manage files directly within the chat interface, improving overall usability and interaction. * refactor(comment-attachments): rename attachment normalization functions for clarity - Updated the `normalizeCommentAttachments` function to `normalizePreviewCommentAttachments` for better context in handling preview comment attachments. - Adjusted the `upsertPreviewComment` and `normalizePreviewComment` functions to utilize the renamed attachment normalization function. - Added tests to ensure that image attachments are correctly saved and retrieved, addressing a regression issue with attachment persistence. These changes enhance code clarity and maintainability while ensuring the functionality for handling comment attachments remains robust. * feat(comment-attachments): enhance comment submission with image and note validation - Updated the `upsertPreviewComment` function to require either a text note or at least one image attachment for comment submission, improving validation logic. - Modified the `BoardComposerPopover` to allow saving comments with only images, enhancing user experience by simplifying the commenting process. - Adjusted the `FileViewer` to support saving comments with image-only notes, ensuring consistency across components. - Improved styles in the chat and home hero components for better visual representation of attachments and comments. These changes collectively enhance the commenting functionality, providing users with more flexibility in how they submit comments while ensuring robust validation. * feat(project-view): implement auto-start for queued chat sends - Replaced the `startingQueuedChatSendIdRef` with a state variable `queuedAutoStartBlocked` to manage the auto-start behavior of queued chat sends. - Updated the `useEffect` to ensure that queued sends are processed one at a time after the active conversation completes, enhancing the chat experience. - Added a test to verify that queued sends auto-start correctly after the active run finishes, ensuring reliable functionality. These changes improve the handling of queued chat messages, providing a smoother user experience during conversations. * feat(project-view): refine auto-start logic for queued chat sends - Replaced the state variable `queuedAutoStartBlocked` with a reference `startingQueuedChatSendIdRef` to manage the auto-start behavior of queued chat sends more effectively. - Updated the `useEffect` to ensure that queued sends are processed sequentially, improving the handling of chat messages during active conversations. - Introduced a new state variable `queuedAutoStartTick` to track the auto-start process, enhancing the responsiveness of the chat interface. These changes improve the reliability and user experience of the chat functionality by ensuring queued messages are handled smoothly and efficiently. * feat(comment-attachments): improve attachment handling in preview comments - Updated the `upsertPreviewComment` function to merge existing and incoming attachments, ensuring that image attachments are preserved when updating comments without new files. - Introduced a new helper function, `mergePreviewCommentAttachments`, to handle the merging of attachments without duplicates, enhancing the robustness of attachment management. - Added tests to verify the correct merging of attachments and the preservation of existing attachments during comment updates, improving overall functionality and user experience. These changes enhance the commenting system by providing better management of image attachments, ensuring users can update comments seamlessly while retaining their attached images. * feat(BoardComposerPopover): enhance popover positioning and measurement - Updated the `popoverAnchorStyle` function to incorporate viewport scroll positions, ensuring the popover remains within visible bounds. - Introduced a new `PopoverSize` type to manage measured dimensions, improving the accuracy of popover placement. - Implemented a `useLayoutEffect` to dynamically measure the popover size and adjust its position accordingly, enhancing user experience during interactions. - Added tests to verify that the popover correctly adjusts its position based on target and viewport dimensions, ensuring it remains fully visible. These changes improve the usability of the BoardComposerPopover by ensuring it is properly positioned within the viewport, enhancing the overall commenting experience. * feat(comment-attachments): enhance image attachment handling in comments - Updated the `normalizeCommentAttachments` function to include image attachments in the comment payload, allowing comments to be submitted with only images. - Introduced a fallback message for comments that consist solely of image attachments, improving user guidance. - Enhanced the `renderCommentAttachmentHint` function to display image attachment details, ensuring users are informed about attached images. - Added tests to verify that image attachments are preserved in comment submissions and correctly rendered in hints, improving overall functionality and user experience. These changes enhance the commenting system by providing better support for image-only comments, ensuring users can effectively utilize image attachments in their interactions. * feat(comment-attachments): refine comment context handling and enhance drag-and-drop functionality - Updated the `normalizeCommentAttachments` function to conditionally omit comment text when the context is set to 'query', improving clarity in comment submissions. - Enhanced the `renderCommentAttachmentHint` function to only display comments when not in 'query' context, ensuring a cleaner output. - Implemented drag-and-drop functionality in the `CommentSidePanel` for reordering comments, improving user interaction and organization of comments. - Added tests to verify the correct handling of comment context and the functionality of the drag-and-drop feature, ensuring robust performance. These changes enhance the commenting system by providing clearer context management and improved usability through drag-and-drop capabilities. * feat(FileViewer, ProjectView): enhance comment attachment handling and status updates - Updated the `FileViewer` component to manage the state of sent comment IDs, ensuring that active previews are correctly updated after sending comments. - Refined the `ProjectView` component to filter out comment attachments from the board-batch source and update their status to 'applying' during processing, improving user feedback on attachment handling. - Introduced logic to handle the removal of sent comment IDs from the preview, enhancing the overall user experience when managing comments and attachments. These changes improve the functionality and responsiveness of the commenting system, providing clearer feedback and better management of comment attachments. * feat(conversation-forking): introduce message-based conversation forking - Added the ability to fork conversations from a specific message, enhancing the chat experience by allowing users to create new conversations that inherit context up to a chosen point. - Updated the CLI commands and help documentation to reflect the new `--fork-after` option, which specifies the message ID to stop copying from. - Enhanced the backend to handle the new forking logic, ensuring that only messages up to the specified ID are included in the new conversation. - Implemented tests to verify the forking functionality, ensuring robust performance and correct behavior when forking conversations. These changes improve the flexibility of conversation management, allowing users to create tailored discussions based on previous interactions. * feat(terminal-service): enhance session output management and memory handling - Introduced new parameters for managing session output, including `maxBufferBytes`, `exitTailBytes`, `flushIntervalMs`, and `flushThresholdBytes`, to optimize memory usage and performance. - Implemented a `trimBuffer` function to efficiently evict old events based on byte and count limits, improving memory management during active sessions. - Added logic to coalesce buffered PTY output into single `data` events, reducing the frequency of event emissions and enhancing performance during high-throughput scenarios. - Updated session event structure to include `byteLength`, allowing for better tracking of output size and memory usage. These changes improve the efficiency and responsiveness of terminal sessions, ensuring better resource management and user experience. * feat(workspace-context): enhance project attachment handling and workspace context management - Introduced `formatProjectAttachmentHint` function to render project attachments in a user-visible order, improving clarity for users referencing attachments. - Added `normalizeWorkspaceContextItems` function to standardize workspace context items, ensuring consistent handling of various context types. - Updated `mergeRunContextSelections` to include workspace items, enhancing the context management during chat interactions. - Enhanced `renderRunContextPrompt` to display active workspace context, providing users with better visibility of their current workspace state. - Implemented tests for new functions to ensure robust functionality and correct behavior in handling project attachments and workspace contexts. These changes improve the user experience by providing clearer context and better management of project attachments within the application. * feat(database, chat): enhance message and conversation data structure - Added `run_context_json` to the `messages` table schema to store contextual information for each message. - Updated migration logic to include the new `run_context_json` field and ensure backward compatibility. - Enhanced conversation retrieval to include `messageCount`, providing better insights into the number of messages per conversation. - Improved attachment handling in the `ChatComposer` component by introducing ordering logic for attachments, ensuring a consistent user experience. - Refactored `SessionModeToggle` to simplify state management and improve tooltip visibility. These changes enhance data management and user interaction within the chat application, providing clearer context and improved functionality. * feat(attachment-handling): improve attachment sorting and context management - Introduced `sortAttachmentsByUserOrder` function to ensure attachments are displayed in a user-defined order, enhancing clarity and usability. - Updated `historyWithApiAttachmentContext` to utilize the new sorting function, improving the context provided with message histories. - Refactored `buildAnthropicMessageContent` to apply sorting for image attachments, ensuring consistent handling across different message types. These changes enhance the user experience by providing better organization and visibility of attachments within the chat application. * feat(chat): enhance conversation listing and loading states - Improved the SQL query for listing conversations to include message counts, providing better insights into conversation activity. - Added loading states to the ChatPane component, enhancing user experience during data fetching. - Implemented a search feature in the conversation history, allowing users to filter conversations by title for easier navigation. - Updated styles for loading indicators and conversation list to improve visual feedback during loading states. These changes enhance the usability and responsiveness of the chat interface, providing users with clearer context and improved interaction capabilities. * feat(chat): optimize suggestion filtering and enhance design system integration - Refactored suggestion filtering in the ChatComposer component to utilize `useMemo`, improving performance by memoizing results based on dependencies. - Added new props in ChatPane for handling plugin and design system details, enhancing the integration of these features within the chat interface. - Updated the FileWorkspace component to manage tab states for design system and browser tabs, improving user navigation and context management. - Introduced modals for displaying plugin and design system details in the ProjectView, enhancing user experience by providing contextual information. These changes improve the efficiency of suggestion handling and enhance the overall user experience in managing plugins and design systems within the chat application. * fix(chat): adjust styling and layout for improved chat interface - Reduced the conversation row height in ChatPane for better alignment with design specifications. - Updated CSS styles across various components to enhance layout consistency, including adjustments to margins, padding, and flex properties. - Improved visual feedback and responsiveness in chat elements, ensuring a more cohesive user experience. These changes refine the chat interface, making it more visually appealing and user-friendly. * feat(comments): implement structural equality checks for comment snapshots - Added `commentSnapshotOverlayEqual` and `commentSnapshotEqual` functions to compare comment snapshots based on their structural properties, improving performance by avoiding unnecessary state updates in the `FileViewer` component. - Updated `HtmlViewer` to utilize these equality checks, optimizing the handling of live comment targets during pointer movements and hover events. - Enhanced the overall responsiveness of the comment system by preventing redundant re-renders when comment snapshots remain unchanged. These changes enhance the efficiency of comment handling and improve user experience in the commenting interface. * feat(chat): enhance comment attachment sorting and order management - Introduced `sortChatCommentAttachmentsByOrder` function to ensure comment attachments are displayed in a user-defined order, improving clarity and usability. - Updated the `currentCommentAttachments` function to utilize the new sorting logic, enhancing the organization of attachments. - Adjusted the order assignment for visual attachments to ensure consistent handling based on existing attachment orders. These changes improve the user experience by providing better organization and visibility of comment attachments within the chat application. * feat(chat): enhance queued send strip with overflow handling and styling improvements - Added overflow handling to the queued send strip, allowing for better visibility of additional queued items when the list exceeds the visible limit. - Updated CSS styles for the chat components, including adjustments to layout, padding, and font sizes to improve overall aesthetics and usability. - Refactored the structure of the queued send row to utilize a grid layout, enhancing alignment and responsiveness of the elements within the chat interface. These changes improve the user experience by providing clearer visibility of queued messages and a more polished interface. * feat(database): add index for created_at and enhance comment retrieval - Introduced a new index on `preview_comments` for `created_at` to optimize query performance when retrieving comments. - Updated the `listPreviewComments` function to order results by `created_at` and `rowid`, improving the organization of displayed comments. - Enhanced the test suite to verify the injection of the new URL preview selection bridge and its functionality in various scenarios. These changes improve the efficiency of comment retrieval and enhance the user experience in the commenting interface. * feat(tooltip): implement tooltip system for enhanced user guidance - Introduced a new `TooltipLayer` component to manage tooltip display across the application, improving user interaction by providing contextual information on hover and focus. - Updated various components to utilize the tooltip system, including buttons and icons, ensuring consistent tooltip behavior and styling. - Enhanced CSS styles for tooltips, improving visibility and responsiveness, while maintaining a cohesive design across the application. These changes enhance the user experience by providing clearer guidance and improving the overall usability of interactive elements. * feat(tooltip): enhance tooltip integration across components - Updated various components to include tooltip functionality, improving user guidance with contextual information on hover and focus. - Added `data-tooltip` and `data-tooltip-placement` attributes to buttons and interactive elements for consistent tooltip behavior. - Enhanced CSS styles to ensure tooltips are displayed correctly and responsively, maintaining a cohesive design across the application. These changes improve the overall user experience by providing clearer guidance and enhancing the usability of interactive elements. * feat(project-view): refactor comment handling and enhance tooltip positioning - Introduced `mergeSavedPreviewComment` function to streamline the management of preview comments, improving clarity and maintainability. - Updated `ProjectView` to utilize the new comment merging function, enhancing the efficiency of comment updates. - Refactored `TooltipLayer` to use x and y coordinates for positioning, improving tooltip display accuracy and responsiveness. - Enhanced CSS styles for tooltips, ensuring better visibility and layout consistency across the application. These changes improve the user experience by providing more efficient comment handling and refined tooltip interactions. * feat(design-files): enhance workspace hint and file handling in project context - Introduced `formatDesignFilesWorkspaceHint` function to provide a detailed overview of the current Design Files workspace, including folder and file listings. - Added limits for the number of folders and files displayed to improve clarity and prevent overwhelming users with excessive information. - Updated the `startServer` function to integrate the new workspace hint, ensuring that the context of existing project files and folders is communicated effectively. - Enhanced tests for the new workspace hint functionality to ensure accurate representation of project context. These changes improve user experience by providing clearer insights into the Design Files workspace and facilitating better project management. * feat(composer): atomic @mention keyboard navigation and deletion * feat(database): add attachments_json field to comments and enhance migration logic - Introduced `attachments_json` field in the database schema for comments to support attachment storage. - Updated migration functions to include the new field, ensuring existing data is properly migrated. - Refactored related SQL queries to accommodate the new field, improving data handling for comments. These changes enhance the comment functionality by allowing attachments to be stored and retrieved effectively. * chore(nix): refresh pnpm deps hash * feat(chat-composer): implement design toolbox for enhanced design actions - Added a new design toolbox feature to the ChatComposer, allowing users to access various design actions such as 'auto-match', 'motion', and 'visual-polish'. - Introduced a state management system for the design toolbox, including hooks for opening and closing the toolbox. - Enhanced the user interface with new components and styles for the design toolbox, improving accessibility and usability. - Implemented functionality to apply design actions directly from the toolbox, streamlining the design workflow. - Added tests to ensure the correct behavior of the design toolbox and its interactions within the ChatComposer. These changes significantly enhance the design capabilities within the ChatComposer, providing users with a more efficient and intuitive design experience. * feat(chat-composer): enhance design toolbox resource management - Expanded the design toolbox functionality in ChatComposer to include a comprehensive resource index, allowing for better organization and retrieval of skills, plugins, MCP servers, templates, connectors, and project files. - Introduced new types and interfaces to support the expanded resource management, improving type safety and clarity in the codebase. - Updated the design toolbox action descriptions and search functionality to reflect the new resource capabilities, enhancing user experience. - Added tests to validate the new resource indexing and search features, ensuring robust functionality. These enhancements significantly improve the design workflow by providing users with a more organized and efficient way to access various design resources. * feat(workspace): enhance workspace context management and UI integration - Introduced a new function `renderWorkspaceContextToolHints` to provide contextual hints based on the type of workspace items (browser, terminal, files, live artifacts). - Updated `ChatComposer`, `ChatPane`, and `FileWorkspace` components to support and display workspace context items, improving user interaction and accessibility. - Enhanced the `QuickSwitcher` and `TabLauncherMenu` components to include workspace context items in search results, allowing users to navigate between tabs and files more efficiently. - Added new translations and updated existing ones to reflect the inclusion of workspace tabs in the user interface. These enhancements significantly improve the usability and functionality of the workspace, providing users with better context and navigation options. * test(e2e): assert Lexical composer content with toHaveText, not toHaveValue The chat composer and home hero input are now Lexical contenteditable editors, not native form controls, so Playwright's toHaveValue (form-only) fails with "Not an input element". Switch all chat-composer-input and home-hero-input content assertions to toHaveText, and assert multi-line soft-break cases with separate toContainText checks since the editor's textContent collapses the newline (the newline reaching the sent payload is already covered by downstream message/payload assertions). * chore(nix): refresh pnpm deps hash * chore(nix): refresh pnpm deps hash * test(e2e): open settings through the entry settings menu The home settings entry is now a menu (EntrySettingsMenu): clicking the gear opens a popover whose "Settings" item opens the full execution-mode dialog. Update the three specs that assumed a single click opened the dialog directly to go through the menu trigger + open-details item. * test(web): drive HomeView context picker through the Lexical helper The home hero input is a Lexical contenteditable, so fireEvent.change / reading .value throws "element does not have a value setter". Switch the MCP+connector first-turn-context spec to setHomeHeroPrompt / homeHeroPromptText like the rest of the file already does. * Fix PR review blockers * Update Nix pnpm deps hash * Enhance project folder routes with error handling and tests - Added checks for project existence in GET, POST, and DELETE folder routes, returning a 404 error if the project is not found. - Updated tests to verify 404 responses for unknown project IDs in folder operations. - Improved folder metadata handling in project routes. - Refactored the TabLauncherMenu component for better UI structure and scrolling behavior. - Adjusted styles for the TabLauncherMenu to improve usability and visual consistency. * Update ProjectView component and enhance design toolbox localization - Modified the ProjectView component to include workspacePanelTrack in chat panel width adjustments. - Updated localization files to add new keys and translations for the design toolbox in English, Simplified Chinese, and Traditional Chinese. - Enhanced user experience by providing comprehensive tooltips and prompts for design toolbox actions. * Add browser use prompt launcher * Cover browser use prompt launcher * Add design toolbox badge translations * Refactor ChatComposer and DesignBrowserPanel components - Removed the design system picker from the ChatComposer component and integrated it into the StagedRunContexts for better context handling. - Updated the DesignBrowserPanel to include a new function for determining viewport icons and modified the browser use categories to reflect changes in action prompts and titles. - Enhanced the HandoffButton component with a new feature to copy the project path to the clipboard, improving user experience. - Added new styles for search input and empty states in design files, enhancing the UI consistency across components. * Enhance ChatPane and DesignBrowserPanel components with new features and styles - Added scroll handling features to the ChatPane component, including scrollable state management and improved user experience during chat interactions. - Updated the DesignBrowserPanel to include new localization keys and improved category titles for better clarity in the browser use prompt. - Enhanced styles for chat log scrolling behavior, providing a more intuitive interface for users. - Implemented keyboard shortcuts for tab navigation in the WorkspaceTabsBar, improving accessibility and user efficiency. * Fix web workspace test hang * Update styles and functionality for workspace tabs and chat components - Adjusted CSS for the MAC_WINDOW_CHROME to improve spacing and margins for better layout. - Enhanced the ChatComposer component to ensure proper tab order and mention handling, improving user experience. - Implemented keyboard shortcuts for navigating workspace tabs, allowing for more efficient tab management. - Updated localization strings for clarity in search prompts across multiple languages. - Improved the HandoffButton component's UI for better visibility and interaction when copying project paths. * Update visual settings flow * Refresh Nix pnpm deps hashes --------- Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com> Co-authored-by: qiongyu1999 <2694684348@qq.com> Co-authored-by: Siri-Ray <2667192167@qq.com> |
||
|
|
4aea5fdb01 |
feat: skip discovery questions for unmodified example prompts (#3257)
* feat: skip discovery questions for unmodified example prompts When a user selects a curated example prompt from the gallery and sends it without modification, the agent now skips all discovery/clarification questions and directly generates the artifact at full quality. Adds an `examplePrompt` metadata flag that injects a dedicated system prompt override instructing the agent to treat the prompt as a complete creative brief requiring showcase-quality generation. Co-Authored-By: Claude Opus 4 <noreply@anthropic.com> * feat: enrich example prompt override with title and pre-filled brief - Pass example prompt title and artifact-type-specific discovery brief through metadata so the agent receives full context without asking - Only skip discovery on the user's first example prompt usage (localStorage gated), subsequent uses follow normal discovery flow - Convert EXAMPLE_PROMPT_OVERRIDE from static string to dynamic builder that interpolates title and brief key-value pairs * fix: prevent handlePromptChange from clearing examplePromptInfoRef The ref is now only cleared by onExamplePromptStatusChange(null) which HomeHero triggers when the user actually edits the text or clicks clear. This prevents the race where usePromptExample sets the ref and then onPromptChange immediately clears it in the same tick. * fix: honor example-prompt discovery skip in API/BYOK mode API/BYOK runs compose their system prompt through @open-design/contracts, whose ProjectMetadata and composeSystemPrompt only knew about skipDiscoveryBrief. Unmodified gallery example prompts therefore skipped discovery in daemon-backed runs but still asked discovery questions in API mode, making the feature mode-dependent. Mirror the daemon's examplePrompt/examplePromptTitle/examplePromptBrief metadata and buildExamplePromptOverride into contracts so both composers behave identically. Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code) --------- Co-authored-by: qiongyu1999 <2694684348@qq.com> Co-authored-by: Claude Opus 4 <noreply@anthropic.com> |
||
|
|
8f9ec58c26 |
Implement Langfuse prompt-stack diagnostics (#3557)
* Implement Langfuse prompt-stack diagnostics Generated-By: looper 0.9.3 (runner=worker, agent=codex) * Redact private var and root prompt paths Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * Redact dev-container workspace prompt paths Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * Reduce prompt stack metadata noise * Normalize arbitrary prompt local paths Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * Preserve semantic slash tokens in prompt telemetry Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * Redact media and srv prompt paths Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * Keep default model bucket in Langfuse * Redact more POSIX prompt roots Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * Redact private var temp prompt paths Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * Avoid duplicate aggregate prompt telemetry content Generated-By: looper 0.9.3 (runner=fixer, agent=codex) * Keep aggregate prompt content in Langfuse diagnostics |
||
|
|
ee2df3bea9 |
[codex] Add safe retry policy contracts (#3569)
* Add safe retry policy contracts * Cap default safe run retry at one attempt Issue #3543 scopes the first implementation to at most one automatic same-run retry. Set DEFAULT_SAFE_RUN_RETRY_MAX_ATTEMPTS to 1 so a first failed retry (attemptCount: 1) suppresses with attempt_limit_reached instead of being eligible for a second retry, and document that the field counts retry attempts rather than the initial run. Update the policy test to assert the one-retry-by-default contract. Generated-By: looper 0.9.3 (runner=fixer, agent=claude-code) |
||
|
|
cad67922a5 |
Merge origin/main into release/v0.9.0 — catch up #3564 BYOK + 7 commits
Resolves MemoryModelInline.tsx and SettingsDialog.execution.test.tsx toward main's newer #3564 BYOK settings rework (this UI surface is newer on main). |
||
|
|
3398ca9826 |
test(daemon): match AMR live-models detection spec to release JSON vela
#3300's detectAgents AMR spec used the legacy text 'vela models' fake; release #3425 switched AMR model loading to 'vela model list --format json'. Point the fake vela at the JSON command so the spec validates the shipped (release) AMR detection path and stops failing 'fallback' != 'live'. |
||
|
|
11f2b994e5 |
Keep integrations CLI guidance aligned with run flow (#3465)
The agent guide still described the old one-shot od run shorthand, while daemon startup duplicated lifecycle code and could exit after the top-level dispatcher completed. This aligns the documented headless path with the current project creation and run start flow, and routes daemon start through the shared startup runtime so the process stays alive until termination. Constraint: Issue #3454 reports the integrations guide no longer matches current CLI behavior Rejected: Keep documenting the old od run --plugin shorthand | it no longer reflects the project plus conversation flow users must run Confidence: high Scope-risk: narrow Directive: Keep CLI guide snippets backed by regression tests when the od command flow changes Tested: pnpm exec vitest run -c vitest.config.ts tests/cli-startup.test.ts tests/daemon-lifecycle.test.ts Tested: pnpm exec vitest run -c vitest.config.ts tests/components/use-everywhere-agent-guide.test.ts Tested: pnpm --filter @open-design/daemon typecheck Tested: pnpm --filter @open-design/web typecheck Tested: git diff --check Not-tested: lint unavailable because affected packages have no lint script Related: #3454 |
||
|
|
fa59871428 |
Merge origin/main into release/v0.9.0 — back-merge to reconcile v0.9.0 with main
Syncs release/v0.9.0 with main so PR #3282 (release/v0.9.0 → main) merges
cleanly. 17 conflicts resolved by commit-time + per-area ownership:
- Comment/edit/preview: keep main (newer). FileViewer combines main's #3438
(pin manual-edit inspector, no full-height panel) + #3347 deck/queue work
WITH release's #3401 hover-card anti-flicker grafted on; #2879 Button kept.
- Toolbar: footer layout (reviewer-validated,
|
||
|
|
b0e7a55a6e |
fix(runtime): handle Gemini stream-json tool events (#3457)
* fix(runtime): handle Gemini stream-json tool events * fix(daemon): treat terminal Gemini errors as fatal |
||
|
|
b70791b0c6 |
Harden sandbox-mode media and tools-dev smoke (#3428)
* Harden sandbox media smoke path * fix(daemon): keep stream-json stdin open after host answer |
||
|
|
b791c14384 |
feat(cli): add od templates subcommand for user-saved templates (#2428)
* feat(cli): add od templates subcommand for user-saved templates
Closes the UI/API/CLI triple for user-saved project templates: the
HTTP layer (POST/GET/DELETE /api/templates) and the New Project ->
Templates UI surface already existed, but external agents could not
list, snapshot, or remove templates without rendering the web UI.
Adds `od templates {help,list,save,delete}` plus the standard
--daemon-url / --json options. `save` takes <projectId> + --name
(and optional --description) and POSTs the same body the UI sends;
`list` and `delete` mirror GET / DELETE /api/templates.
New tests/cli-templates.test.ts pins the contract by spinning up a
tiny HTTP stub and exec-ing the real cli.ts entry, so the SUBCOMMAND
dispatch, flag parsing, missing-arg exit codes, and JSON output mode
are all covered end to end.
* fix(cli): surface clean daemon-unreachable error from `od templates` verbs (#2428 review follow-up)
Reviewer P2 from lefarcen on #2428: each `od templates` sub-verb
(`list`, `save`, `delete`) called `fetch()` without a try/catch, so
when the daemon wasn't running Node threw a raw
`TypeError: fetch failed` instead of the
`failed to reach daemon at <url>: <code>` shape every other CLI
surface emits via `surfaceFetchError`.
Wrap each `fetch` in the same pattern `runAutomation` /
`runResearch` / the project verbs already use:
let resp;
try {
resp = await fetch(...);
} catch (err) {
surfaceFetchError(err, base);
process.exit(3);
}
Adds three regression cases — one per sub-verb — pointing the CLI at
an unreachable port to assert exit code 3 plus the clean error string
and no raw `TypeError` leak.
* fix(cli): make od templates positional id flag-order tolerant + map 404/400 to precise error codes (#2428 review follow-up)
Reviewer (#2428 non-blocking, round 3) found two robustness issues:
1. `od templates save <projectId>` and `od templates delete <id>`
both required the positional id to be the first token after the
sub-verb. A headless caller that put shared options first —
`od templates save --daemon-url http://... proj-1 --name Cards`
— would hit the missing-id usage path before reaching the daemon.
Switch to a `positionalArgs(rest)` helper that mirrors
`runAutomation`, stepping past `--flag value` pairs for every
templates string flag so the id can appear before or after flags.
2. `structuredHttpFailure(resp)` with the default fallback maps any
non-OK templates response to `daemon-not-running`, but the
`/api/templates` route returns 404 for an unknown source project
and 400 for body validation — reachable user errors while the
daemon is up. Map 404 → `project-not-found` and 400 →
`missing-input` on save, and 404 → `template-not-found` on delete
(new code, exit 74, alongside `project-not-found`/`run-not-found`).
Agents reading the exit number alone can now branch correctly
without parsing the envelope.
Five new regression tests pin:
- positional id after `--daemon-url` for save and delete
- save → 404 surfaces `project-not-found` (exit 68)
- save → 400 surfaces `missing-input` (exit 67)
- delete → 404 surfaces `template-not-found` (exit 74)
- the existing 11 cases still pass under the new flag parsing
* test(cli): reserve-and-release a free port for unreachable-daemon checks (#2428 review follow-up)
The unreachable-daemon regressions previously pointed the CLI at stub.baseUrl's port + 1, but the OS only guaranteed the stub's ephemeral port itself was free — port + 1 could already be bound by another local process on a shared CI host. If that happened, the three cases exercised whatever server was on that port instead of the connection-refused path and could fail or pass for the wrong reason.
Switch to a reserve-and-release helper: open a probe HTTP server on port 0, capture the OS-assigned port, close the server, then point the CLI at that exact port. The connection fails ECONNREFUSED on every platform because nothing is listening on it now and the port was deliberately picked from the same ephemeral pool the kernel uses for free-port allocation.
* fix(cli): align `od templates delete` with the daemon's idempotent contract (#2428 review follow-up)
DELETE /api/templates/:id in the real daemon (project-routes.ts:729-731,
server.ts:6064-6066) calls deleteTemplate(...) unconditionally and
returns { ok: true } for unknown ids. The CLI's earlier 404 special
case mapped a status the production route never emits to a
template-not-found exit code that could not fire, and the stub-only
regression test documented behavior the shipped API does not expose —
exactly the CLI/API drift the dual-track exposure rule is meant to
avoid.
Drop the 404 branch, the RECOVERABLE_EXIT_CODES entry for
template-not-found, and the stub-only regression. Any unexpected
non-2xx still falls through to structuredHttpFailure(resp). Delete
stays documented as idempotent success until the daemon contract
itself changes in a follow-up.
Surfaced by Siri-Ray and mrcfps's matching inline reviews on cli.ts:5135.
* fix(cli): preserve daemon flat-string error messages in structuredHttpFailure (#2428 review follow-up)
POST /api/templates returns flat `{ error: '<message>' }` bodies for
400/404 (project-routes.ts:669, :675, :679), but structuredHttpFailure
expected the nested `{ error: { code, message } }` shape. With a flat
body, parsed.error.message was undefined and the structured envelope
collapsed to a `HTTP 400: ` message — losing the only diagnostic the
daemon actually returned to headless callers.
Normalize a string-shaped error.body into `{ message }` before the
recoverable-code lookup, so:
- The exit-code mapping stays the same (still falls through to the
fallback code at the call site).
- envelope.error.message now carries the daemon's literal text
(`source project not found`, `name required`) instead of an empty
HTTP placeholder.
The two save-error regressions are also realigned to stub the flat
payload the route actually emits and now assert on the message body,
so the CLI/daemon contract stays locked across both the structured
and the legacy flat shapes.
Surfaced by mrcfps's inline review on cli-templates.test.ts:480.
|
||
|
|
a6198e22fd |
Improve run failure classification and Langfuse correlation (#3412)
* Classify run failures in analytics * Add Langfuse delivery observability * Handle normalized cache token aliases * Fix normalized cache token accounting * Cover CLI token usage analytics * Add stderr diagnostics telemetry * Wire Langfuse reporting through inline message route * Add run failure telemetry smoke coverage * Add run observability regression coverage * Add asked_user_question to run_finished contract test fixture main introduced asked_user_question as a required RunFinishedProps field. The branch's run_finished contract test built the props fixture without it, so the post-merge Preflight typecheck failed. Supply the field in the base fixture so the contract test compiles against the merged contract. Generated-By: looper 0.9.2 (runner=fixer, agent=claude-code) * Expand observability regression matrices * Add failure detail telemetry classification * Classify permission request lifecycle failures * Classify upstream stream closure failures * Classify socket closed API failures * Count stderr lines from merged stream in analytics summary summarizeRunDiagnosticsForAnalytics summed per-chunk line counts, but stderr chunks are not line-aligned. A logical line split across two chunks was counted twice, inflating stderr_line_count_bucket. Concatenate chunks first, then count, matching collectStderrTailSummary. Generated-By: looper 0.9.2 (runner=fixer, agent=claude-code) * Fix first-token timing and Langfuse model labeling Drop tool_use from FIRST_TOKEN_AGENT_EVENT_TYPES so firstTokenAt is only stamped by token-producing events; tool-first runs no longer under-report time_to_first_token_ms / spawn_to_first_token_ms. Thread agent_reported_model out of the usage scan in langfuse-bridge and use it for turn.model when the request did not pin an explicit model, so Langfuse traces label the resolved model and agree with PostHog run_finished instead of keeping the default placeholder. Generated-By: looper 0.9.2 (runner=fixer, agent=claude-code) * Stamp antigravity first-token only when buffered stdout is flushed The antigravity stdout handler stamped firstTokenAt as soon as any buffered chunk arrived, but on the OAuth-required path agy prints the login URL to stdout and the close-time auth-prompt guard suppresses that buffer without ever flushing it. firstTokenAt was still set, making time_to_first_token_ms / spawn_to_first_token_ms look artificially fast for that failure mode. Record only the first chunk's arrival time at buffer time and stamp firstTokenAt from it at flush time, so suppressed OAuth-prompt runs never report a TTFT for output the user never saw. Generated-By: looper 0.9.2 (runner=fixer, agent=claude-code) * Re-derive Langfuse delivery state at run completion time The PostHog run_finished sink captured langfuseDeliveryForAnalytics once when POST /api/runs was handled and reused it in the terminal callback, so a long-running run could publish stale langfuse_expected / langfuse_delivery_status / langfuse_drop_reason if the user flipped telemetry consent or relay config mid-flight. The Langfuse sink (reportRunCompletedFromDaemon) re-reads app config at completion, so the two paths could disagree. Recompute deriveLangfuseDeliveryState inside the run-completion callback so both sinks read the same completion-time eligibility. Generated-By: looper 0.9.2 (runner=fixer, agent=claude-code) * Carry total-only token usage and drop default model label in Langfuse bridge Generated-By: looper 0.9.2 (runner=fixer, agent=claude-code) --------- Co-authored-by: Amy <1184569493@qq.com> |
||
|
|
502526c5cc |
fix(daemon): don't fail AMR runs that do tool work but emit no text (#3487)
An AMR (ACP) run that completes its turn doing real work — tool calls / file edits — but emits no closing assistant text was failed with "ACP session completed without producing any assistant text. Refresh the AMR model list, choose a supported model, and retry this run." The prompt-complete handler only checked `!emittedTextChunk`, and the `modelUnavailableErrorCode` guard is set unconditionally for every AMR run, so the check reduced to "no assistant text". `emittedTextChunk` is only set by `agent_message_chunk`; `tool_call` / `tool_call_update` updates were ignored. So a model that edits a file via a tool and ends without a chatty summary (common with gemini-3-flash-preview) had its successful work reported as a model-unavailable failure — verified end-to-end: the tool's file was written, yet the run was marked failed. Track tool-call activity and only report the no-output failure when the turn produced neither assistant text nor any tool call. A genuinely empty turn (the real unsupported-model signal) still fails. Tests: a tool-only turn with no assistant text no longer errors; an empty turn with no text and no tool calls still fails with the same message. |
||
|
|
6634790fd4 | fix(cli): discover tools-dev daemon URL (#2807) | ||
|
|
194f26ce8c |
fix(prompt): tighten Comment scope from soft guide to hard constraint (#2796)
* fix(prompt): tighten Comment scope from soft guide to hard constraint The <attached-preview-comments> block opened with 'Scope: apply the user request to the attached preview target by default. ... Preserve unrelated elements.' That reads as a soft preference, and in practice agents still refactor sibling sub-pages, parent layout, or global CSS when the user only intended the attached element. Replace with a hard scope directive: Hard scope: change ONLY the elements identified below by selector / position / pod members. Do NOT modify sibling sub-pages, parent layout, global CSS, design tokens, or unrelated rules even if you notice issues there — surface those as a follow-up note in your reply instead of editing them. If the user's request cannot be satisfied without touching outside this scope, ask the user before proceeding. For visual marks, inspect the screenshot and modify the marked region first. Applied symmetrically to apps/web/src/comments.ts and apps/daemon/src/server.ts so the web composer and the daemon-side attachment renderer stay in sync. * ci: re-trigger checks (transient checkout-auth flake on previous run) * test(comments): assert hard-scope sentence text in web and daemon renderers --------- Co-authored-by: nicejames <nicejames@gmail.com> |
||
|
|
a7440af9e5 |
Revert "Merge pull request #3410 from nexu-io/fix/deck-comment-slide-scope-v0.9.0" (#3481)
This reverts commit |
||
|
|
ed5fef88a1 |
fix(web): preserve bulk edit file paths (#3475)
Generated-By: looper 0.9.3 (runner=worker, agent=codex) Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
adcb655108 |
fix(connectors): explain Composio custom auth requirement (#3464)
* fix(connectors): explain Composio custom auth requirement * fix(connectors): rediscover custom Composio auth configs |
||
|
|
dbcb5a0b25 |
Merge pull request #3410 from nexu-io/fix/deck-comment-slide-scope-v0.9.0
Fix deck comment slide scoping |
||
|
|
f06063baca |
feat(cli): add MMS redesign workflow (#3311)
* feat(cli): add MMS redesign workflow Add a CLI-oriented redesign workflow, MMD route env handoff for Claude launches, and bundled style skills for local Open Design redesign jobs. Agent-Model: gpt-5 Agent-Family: openai Agent-Session: 019e6ceb-c33d-7cd3-bff0-cbc20c642197 Agent-Step: 0.1.0 * fix(cli): preserve redesign import auth Agent-Model: gpt-5 Agent-Family: openai Agent-Session: 019e6ceb-c33d-7cd3-bff0-cbc20c642197 Agent-Step: 0.0.4 --------- Co-authored-by: Codex <gpt-5@openai.com> |
||
|
|
3da33f92a1 |
Harden sandbox orchestration daemon chokepoints (#3420)
* Harden sandbox orchestration chokepoints * Cover web app public copy in neutrality guard |
||
|
|
1d48254c4e | fix: capture antigravity logs before print mode (#3395) | ||
|
|
66522f0bc5 | Fix loading of preview files from DS (#3418) | ||
|
|
b47b092196 | Fix deck comment slide scoping | ||
|
|
3083388a1a |
Add launch review regression coverage (#3300)
* Add main launch review E2E coverage * Add daemon launch review regression coverage * Tighten plugin authoring completion regressions * fix(web): preserve deck slide on preview switches Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * Add project detail regression coverage |
||
|
|
d285cb373a |
feat(daemon): per-agent MCP installer — plugin marketplace + 14-agent planner (#3442)
* feat: add per-agent MCP installer with source-deploy fallback
Wire Open Design's stdio MCP server into 14 coding agents via a single
`curl ... | sh -s <agent>` command. Two paths, chosen automatically:
Path 1 — a local `od` is found (PATH, packaged app, prior build):
register the agent via `od mcp install <agent>`.
Path 2 — no `od`: deploy from source (clone + pnpm install + build +
link + background daemon), then register.
- od mcp install <agent>: per-agent planner with cli/json/manual
strategies; resolves the launch spec from the running daemon and
falls back to a default stdio spec when offline.
- install-agent.sh: POSIX sh bootstrap that locates or source-deploys
`od` before forwarding; probes past the Unix octal-dump `od`.
* feat(installer): support OD_REF to pin clone branch for source deploy
* fix(installer): fail clearly when OD_HOME is a non-empty non-checkout dir
* fix(installer): place server name before -e flags for claude mcp add
claude's `mcp add` treats `-e/--env` as variadic (`<env...>`), so emitting
`-e KEY=val <name> --` made the CLI swallow the server name as an env value
("Invalid environment variable format: open-design"). Put the name first,
then env flags, then `--`, matching `claude mcp add <name> -e K=v -- <cmd>`.
* feat(plugins): claude/codex one-command install via plugin marketplace; drop install.sh
The install.sh route was load-bearing on a non-existent URL: PR body
advertised `curl -fsSL https://open-design.ai/install.sh | sh -s <agent>`
but Vercel serves the Next.js index page at `/install.sh`, not the
shell script. Bootstrap users got 173KB of HTML piped into sh and
nothing installed.
Re-scoped per maintainer call (lefarcen, 2026-06-01): drop the
self-deploy path entirely, assume the user installs `od` themselves
(brew / npm / DMG), and focus PR #3431 on the one-thing it
genuinely owns — wiring `od mcp` into the user's coding agent.
## Two install paths now
Agent User runs
───────────────── ──────────────────────────────────────────────────────
claude claude plugin marketplace add nexu-io/open-design
claude plugin install open-design@nexu-io/open-design
codex codex plugin marketplace add \
git@github.com:nexu-io/open-design.git
codex plugin install open-design@nexu-io/open-design
cursor / copilot od mcp install <slug>
cline / opencode (writes the agent's own JSON config — see
openclaw / etc. apps/daemon/src/mcp-agent-install.ts for the 14
supported agents)
Both paths land on the same launch spec: `od mcp --daemon-url <url>`
running as a stdio server, with whatever env the local daemon hands
back from /api/mcp/install-info. The plugin manifest hard-codes
`command: "od"` so it depends on `od` being on PATH — the maintainer's
existing install (brew/npm/DMG) is the source of truth, plugin install
is purely the wiring.
## What this commit does
- Delete deploy/scripts/install-agent.sh (~240 lines) — load-bearing
but unreachable (Vercel doesn't serve it), and the source-deploy
path it gated (clone / pnpm install / build daemon / link bin) is
out of PR scope per the re-scope above.
- Add .claude-plugin/marketplace.json — owner=nexu-io, exposes
open-design plugin at ./plugins/open-design.
- Add plugins/open-design/.claude-plugin/plugin.json — name +
displayName + description + mcpServers pointer to .mcp.json.
- Add plugins/open-design/.mcp.json — stdio server `od mcp
--daemon-url http://127.0.0.1:7456`, same shape /api/mcp/install-info
hands back.
The TypeScript planner + executor (apps/daemon/src/mcp-agent-install.ts,
runMcpInstall in cli.ts) and its tests are unchanged — they're the
true core for the 10 agents that don't have plugin marketplaces.
## Verified
- JSON validates for all 3 manifests.
- Daemon already serves stdio MCP on `od mcp` (pre-existing,
/api/mcp/install-info confirms).
- `claude plugin install open-design@nexu-io/open-design` flow: I
validated the same manifest shape on a sister repo (nexu-xray,
https://github.com/nexu-io/agent-pr-explore) and it installs cleanly
on Claude Code + codex from a single marketplace manifest.
## NOT verified yet (worth a smoke on this branch)
- The full `od mcp install <agent>` flow for the 10 non-plugin
agents (cursor / copilot / cline / opencode / openclaw / antigravity
/ gemini / trae / kimi / hermes-pi-vibe-print-only). The unit tests
cover plan generation; an end-to-end against a real `claude mcp
list` / a real cursor.mcp.json would catch shape regressions.
---------
Co-authored-by: qiongyu1999 <2694684348@qq.com>
Co-authored-by: lefarcen <ontf116@gmail.com>
|
||
|
|
601183efbb |
feat(daemon): load AMR model presets before remote catalog (#3425)
* spec * impl * fix * remove default model content * fix(amr): keep model catalogs fresh across env changes Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * fix(amr): bust logout cache and stop preset polling Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * test(amr): cover logout cache invalidation and bounded polling Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * fix(amr): start preset polling before agent probe Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * fix(amr): clear stale web cache on env rescan Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * fix(amr): restart preset polling after sign-in Generated-By: looper 0.9.2 (runner=fixer, agent=codex) * fix(daemon): remove extra AMR spawn env arg Generated-By: looper 0.9.2 (runner=fixer, agent=codex) |
||
|
|
fabfddaede |
feat(daemon): add contained project preview URLs (#3246)
* feat(daemon): add contained project preview URLs * fix(daemon): tolerate coarse artifact mtimes * fix(daemon): validate project preview scopes |
||
|
|
512e01405f |
fix(web): queue preview comments while busy and pin deck markers (#3347)
* fix(web): queue preview comments while busy and pin deck markers While a chat run is in flight, preview comments now queue instead of showing a stuck Sending state. Deck slide changes no longer collapse comment markers to 0,0 by filtering hidden targets and persisting slideIndex. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): stop comment overlay jitter from redundant target sync Skip React updates when live comment target bounds are unchanged, refresh deck targets only on slide changes, and drop characterData from the selection-bridge mutation observer to avoid streaming text churn. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): keep comment target metadata fresh * fix(web): refresh active comment text mutations * fix(daemon): key preview comments by deck slide --------- Co-authored-by: chaoxiaoche <chaoxiaoche@chaoxiaochedeMacBook-Pro.local> Co-authored-by: Cursor <cursoragent@cursor.com> |