mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
4f15da139a97d4b29038e12a472bc0aff2e60f3c
70
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0fecb15baa |
chore(release): bump main to 0.12.1 ahead of stable 0.12.0 (#4900)
Stable shipped 0.12.0 (tag open-design-v0.12.0, 2026-06-26) but main's packaged base version stayed at 0.11.1. release-beta's metadata guard requires the packaged base version to be strictly greater than the latest stable, so the daily beta build (notify-daily-feishu, 01:00 UTC) has failed every morning since 2026-06-27 with: packaged base version 0.11.1 must be strictly greater than latest stable 0.12.0 Bump all 18 workspace package.json versions in lockstep to 0.12.1 so main leads stable again. Verified the real prepare-beta guard now resolves 0.12.1-beta.1 (EXIT 0) against the live stable/beta feeds. |
||
|
|
8b9b169673 |
ci: add cost-sensitive runner tiering (#4764)
* test persistent contabo runner poc * test persistent runner web workspace poc * test persistent runner local cache setup * test persistent runner aggressive setup poc * test persistent runner web postinstall profile * test restore stable persistent runner poc * test keep persistent runner web tests default * test route persistent poc to zxiyun runner * test relax web vitest timeout on persistent poc * test harden web vitest cases for persistent runner * test add runner perf probe * test isolate runner perf probe dispatch * test pin runner perf probe node * test expand runner perf probe matrix * ci: route heavy jobs through runner modes * ci: keep web workspace tests on blacksmith * test: update web runner mode assertion * ci: route cost-sensitive runner tiers * ci: move preflight to hosted runner * ci: downshift blacksmith ui runners to 4vcpu * test: fix file viewer timeout after merge * ci: route e2e vitest to hosted default * ci: centralize runner profile selection * test: type runner profile assertions * ci: route e2e vitest to default blacksmith * ci: remove runner experiment probes * test: restore postinstall guard coverage Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * test: cover postinstall script contract * test: move postinstall guard to e2e --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
0bf1b6d6b8 |
[codex] converge release workflows and stable dry-runs (#4390)
* fix(tools-pack): use junctions for Windows standalone peer deps * fix(desktop): expose IPC during startup * fix(tools-pack): preserve Windows inspect diagnostics * fix(tools-pack): report Windows inspect status errors * fix(packaged): use Electron net fetch for app protocol * fix(packaged): load Windows renderer from web sidecar * fix(desktop): show Windows packaged window during startup * fix(packaged): disable Windows GPU startup * fix(tools-pack): keep Windows core smoke observable * fix(packaged): remove Windows startup probes * fix(tools-pack): trace Windows desktop IPC status * fix(tools-pack): add Windows IPC diagnose loop * fix(release): default beta-s Windows updater feed * chore: clean merged test eof * refactor(release): unify prerelease channel model * chore(release): close prerelease doc escape hatches * refactor(release): converge release channel workflows * fix(release): install toolchain in metadata jobs * fix(release): build release package before contracts * chore(release): bump development version to 0.10.1 * fix(e2e): seed windows packaged smoke runtime config * fix(release): install toolchain for metadata publish * fix(release): materialize betas metadata checkout * chore(release): bump development version to 0.10.2 * fix(release): allow betas metadata cold start from s3 * fix(e2e): support betas packaged update scenarios * fix(release): pass betas channel into packaged smoke * fix(release): set betas channel during self-hosted builds * fix(release): verify counted channel reservations * fix(release): use pnpm cmd for betas windows publish * fix(release): add betas manifest artifact fallback * fix(release): skip beta-s public metadata fetch * fix(release): read beta-s manifests from storage * fix(release): cache beta windows tools-pack builds * fix(release): inline beta mac tools-pack builds * fix(pack): deep sign unsigned mac bundles * docs(pack): document payload-first beta updater validation * fix(release): align preview tools-pack cache flow * fix(release): align prerelease tools-pack cache flow * fix(release): pass github token to prerelease metadata * fix(release): setup pnpm before feishu notify * fix(release): add stable dry-run prepublish flow * fix(release): accept completed prerelease metadata gate * fix(release): require stable release branches * fix(release): converge r2 access checks * fix(updater): use release channel parser for defaults * fix(updater): harden windows payload relaunch * fix(release): converge updater smoke fixture contract * test(e2e): require silent updater fixture output * fix(release): align stable windows smoke build path * fix(ci): include release workspace in validation * fix(ci): repair release validation lanes Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) * fix(ci): restore zero-install Feishu notification Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
d3896fa51a |
[codex] Clean deprecated launcher payloads on updater startup (#4524)
* fix(packaged): recover stale launcher and sidecar state * fix(packaged): write launcher cleanup from installer sync * perf(tools-pack): reuse windows payload caches * perf(tools-pack): avoid slow windows 7z filters * fix(tools-pack): bound windows payload archive hangs * test(packaged): stabilize sidecar tests on windows * fix(tools-pack): harden launcher runtime sync helper * fix(tools-pack): invalidate nsis cache for installer helpers * fix(tools-pack): hash nsis helper source in bundled cli * fix(packaged): restart when existing desktop has stale sidecars * chore(release): bump beta base to 0.11.1 * fix(e2e): seed windows smoke onboarding in runtime data * ci(release): let beta runs use default queueing * ci(release): restore beta concurrency guard * ci(release): enable beta mac x64 by default * ci(release): disable beta mac x64 by default * fix(updater): clean deprecated launcher payloads on startup * fix(e2e): align stable dry-run fixture version Generated-By: looper 0.9.10+codex.autoclean (runner=fixer, agent=codex) --------- Co-authored-by: Looper <looper@noreply.github.com> |
||
|
|
15d3759834 |
[codex] Optimize CI topology and Playwright suites (#4460)
* Consolidate PR validation into ci * Tune absorbed CI runner tiers * Fold visual validation into CI Playwright shards * Run PR shards during manual CI dispatch * Optimize CI topology and scopes * Increase UI P0 Playwright workers * Relax visual Playwright timeout |
||
|
|
39cad2b8a5 | chore(release): bump version to 0.11.0 for release/v0.11.0 | ||
|
|
30b8eac48c |
chore(release): bump version to 0.10.2 on main (#4387)
main read 0.10.1 (== latest stable 0.10.1), so the daily beta build's strictly-greater-than-stable version guard refused to produce a beta from main. Advance the 0.10.x dev line to 0.10.2 across the same 16 lockstep workspace package.json that #4381 bumped, and align the packaged-smoke stable dry-run fixture to 0.10.2. This continues the existing beta line on R2 (0.10.2-beta.4) so a build from main produces 0.10.2-beta.5. |
||
|
|
a3a5f02d87 |
chore(release): bump version to 0.10.1 on main (#4381)
Back-fill the 0.10.1 version bump that shipped via the release/v0.10.1 branch (tag open-design-v0.10.1, already published) but never merged back to main. The feature/perf content of that release already landed on main via #4198, #4203 and #4202; only the version-number bump and the packaged-smoke stable fixture were left behind, so main still read 0.10.0. This applies the release-specific deltas onto current main: - bump version 0.10.0 -> 0.10.1 across the 16 workspace package.json in the 0.10.x release set (apps/daemon, apps/desktop, apps/landing-page, apps/packaged, apps/web, e2e, root, packages/contracts, packages/download, packages/host, packages/launcher-proto, packages/platform, packages/sidecar-proto, packages/sidecar, tools/dev, tools/pack) - align e2e packaged-smoke stable fixture to 0.10.1 launcher-proto was added to main after the 0.10.1 release branch was cut, so it was not in the original release commit; it is part of the lockstep 0.10.x release set (private workspace package, sibling of sidecar-proto), so it is bumped here to keep main release metadata consistent. Independently-versioned workspace packages (agui-adapter, components, diagnostics, metatool, plugin-runtime, registry-protocol, tools/serve, telemetry-worker) are intentionally left untouched. Supersedes the stale release/v0.10.1 PR (#4205). |
||
|
|
a0beba92f9 |
[codex] lint craft references in guard (#4239)
* chore: lint craft references * fix: validate bundled plugin craft references --------- Co-authored-by: Jeshua09090 <jeshuaelpro@outlok.com> |
||
|
|
34053d95bf |
Pin sandbox contract shapes and ownership guards (#3429)
* Pin sandbox contract shapes and ownership guards * fix(web): guard alias import escapes |
||
|
|
d055737de7 |
[codex] Add PR UI P0 gate (#4142)
* add PR UI P0 gate * fix(ci): keep critical UI check in required workflow Generated-By: looper 0.9.7 (runner=fixer, agent=codex) |
||
|
|
e94acc2702 |
add cross-app import boundary check to pnpm guard (#4069)
* feat(guard): enforce the cross-app import boundary in pnpm guard Adds a cross-app import check that scans apps/* sources for imports reaching into another app (relative paths, @open-design/<app> package specifiers, or apps/-rooted paths) and fails pnpm guard with the offending file:line. The web/daemon integration boundary (HTTP APIs + packages/contracts) was previously enforced only by human review. The deliberate packaged -> desktop ./main export is allowlisted with a documented reason; further exceptions must be added the same way. * fix(guard): harden cross-app import scanning Generated-By: looper 0.9.6 (runner=fixer, agent=codex) * fix(guard): fail on unreadable app manifests Generated-By: looper 0.9.6 (runner=fixer, agent=codex) * fix(guard): reject unnamed app manifests Generated-By: looper 0.9.6 (runner=fixer, agent=codex) * fix(guard): catch require.resolve app imports Generated-By: looper 0.9.6 (runner=fixer, agent=codex) * fix(guard): detect createRequire app imports Generated-By: looper 0.9.6 (runner=fixer, agent=codex) * fix(guard): catch CommonJS node module createRequire Generated-By: looper 0.9.6 (runner=fixer, agent=codex) |
||
|
|
a3a222c6c0 |
fix: small UX/correctness fixes (composer, media settings, run status, nav tabs) (#3814)
* fix(web): drop the border around the composer "+" trigger
The base button{} rule applied a 1px border to the ComposerPlusMenu
trigger, leaving a visible box around the home composer's "+" icon. Make
the trigger transparent (border + background) with a subtle hover, so it
reads as a plain icon button consistent with the project composer.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
* feat(web): defer media generation settings to in-task AI questions
HyperFrames / Image / Video / Audio composer modes no longer surface
inline pre-flight dropdowns (aspect ratio, duration, model, resolution,
audio kind). Image/Video keep only the design-system picker; HyperFrames
and Audio keep none. Those settings are now asked for by the agent during
the run via the existing question-form / AskUserQuestion flow, mirroring
how Prototype and Slide deck already defer their settings.
- footerInputNamesForChip: image/video -> ['designSystem'], hyperframes/
audio -> [].
- metadataForHomeMediaComposer no longer seeds imageAspect/videoAspect/
videoLength/audioKind/audioDuration; only kind (+ the hyperframes-html
route discriminator) and any picked prompt template.
- queryTemplateForSurface drops the {{ratio}}/{{duration}}/{{model}}/
{{resolution}}/{{voice}} slots from the prompt body.
- system.ts: image now prints "(unknown - ask: ...)" for model/aspect
instead of silently defaulting, so the agent asks (video/audio already
did).
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
* fix(daemon): don't mark a run failed when it produced an artifact
classifyChatRunCloseStatus decided run status purely from the process
exit (code/signal/turnCompletedCleanly) and never checked whether the run
actually produced an artifact. A non-zero exit during teardown (e.g. a
SessionEnd hook) after the deliverable was already written showed a red
"failed" card for work that succeeded.
Add an artifact-aware carve-out: a non-zero NORMAL exit (real exit code,
never a signal) that produced a confirmed artifact this run is classified
succeeded. Gated on code != null && code !== 0 so a signal kill
(OOM / external kill / container shutdown) is never flipped, preserving
the existing guard. The signal comes from scanRunEventsForRetrySideEffects
(artifactWriteSeen || liveArtifactSeen).
Also add a one-shot backfill script (pnpm backfill:failed-runs) that
repairs existing rows: failed runs whose project dir contains an
*.artifact.json are corrected to succeeded.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
* fix(web): persist the entry nav-rail expanded state
The rail's open/collapsed state lived only in EntryShell's useState, so it
reset to collapsed whenever EntryShell remounted — e.g. returning to home
after visiting a project, or a reload. Persist it to localStorage
(SSR-guarded read/write; App is loaded with ssr:false so there's no
hydration mismatch) so the rail keeps its state across navigation and
reloads.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
* fix(web): collapse all entry sections into the single leftmost tab
Clicking a sidebar section (Projects / Automation / Design systems /
Plugins / Integrations) opened a second workspace tab instead of reusing
the leftmost one. Treat the leftmost tab as a single entry-tab singleton
(any view) rather than a Home-view singleton: navigating to any entry view
switches that one tab's view in place, and its label follows the view.
Project / marketplace tabs are unchanged and still open to the right.
- syncStateToRoute: any kind:'home' route reuses the entry tab found by
kind alone and updates its view; project-route guard broadened so
opening a project from any entry view appends rather than replaces.
- normalizeTabsState: dedup / must-exist / leftmost-pin invariants keyed
by kind==='entry' instead of view==='home'.
- The non-closable / pinned / drag-pin / new-tab-reuse sites switch from
view==='home' to kind==='entry'.
Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
* fix(scripts): correlate backfill repair to the run that produced the artifact
The failed-runs backfill was scoped only by projectId: a single
*.artifact.json anywhere under <dataDir>/projects/<id> flipped every
failed message row in that project to succeeded. Project dirs are
long-lived and accumulate sidecars from unrelated runs, so one
successful artifact reclassified unrelated real failures — an
irreversible data-integrity bug once run without --dry-run.
Now a row is repaired only when the failed message's own
produced_files_json lists a file whose <name>.artifact.json sidecar
still exists on disk, mirroring the daemon's artifactProducedThisRun
carve-out. Path-traversal/absolute refs are rejected.
Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code)
* fix(web): strip deferred media defaults from the forwarded run inputs
Hiding the media footer pills (model / ratio / resolution / duration /
audioType / voice) stopped them rendering but did not stop their seeded
defaults from reaching the run. buildHomeMediaComposer still seeds
`ratio: 16:9`, `duration: 5`, `audioType: speech`, etc., and submit()
forwarded submittedActive.inputs as pluginInputs after stripping only
fidelity / slideCount / speakerNotes — so an Image/Video/Audio/HyperFrames
run arrived with baked-in defaults and the first-turn AskUserQuestion
discovery flow had nothing left to ask.
Extend ARTIFACT_FOOTER_FIELD_NAMES to cover the deferred media fields, and
split submit() into apply-inputs vs forwarded-inputs: the plugin is still
(re)applied with the full inputs (od-media-generation validates `subject`),
while only the stripped set is forwarded to onSubmit. Computing
inputsEqual against the apply-inputs avoids a spurious re-apply round-trip
on submit. subject / style / aspect / mediaKind are intentionally kept.
Red spec: tests/components/HomeView.media-options.test.tsx "strips deferred
media settings from the forwarded pluginInputs" — red on the pre-fix
branch (pluginInputs.model === doubao-seedance-2-0-260128), green here.
Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code)
* fix(web): assert prototype fidelity deferral on the forwarded run inputs
The deferred-media-defaults change re-applies the plugin with its full
inputs (hyperframes needs `model` to pick its pipeline, od-media-generation
needs `subject`), so the prototype apply call now legitimately carries
`fidelity`. HomeView.prefill's "binds the Home rail Prototype chip" case
still asserted `fidelity` was absent from the apply-call body, which is the
wrong surface — the deferral invariant is that `fidelity` must not reach the
run, not that it is stripped before apply.
Move the assertion onto the forwarded `pluginInputs` from onSubmit, where the
deferral actually holds, and note in HomeView why hyperframes keeps `model`
at apply time. No source behavior change.
Generated-By: looper 0.8.1 (runner=fixer, agent=claude-code)
* fix(web): strip deferred media defaults from the run-facing snapshot too
Stripping the deferred footer/media fields from onSubmit.pluginInputs was
not enough: submit() still re-applied the plugin from the FULL inputs and
forwarded that snapshot's id as appliedPluginSnapshotId. The daemon renders
`## Plugin inputs` verbatim from snapshot.inputs (server.ts pluginPromptBlock,
packages/contracts plugin-block.ts) and tells the agent not to re-ask about
anything listed there, so an Image/Video/Audio/HyperFrames run still arrived
with `ratio: 16:9` / `duration: 5` / `model: …` baked into the prompt and the
first-turn AskUserQuestion discovery flow stayed suppressed.
Resolve the run-facing snapshot from the deferral-stripped inputs and compare
inputsEqual against the cached snapshot's inputs so the strip forces a fresh
apply. Stripping only removes non-required fields (subject / style / aspect /
mediaKind survive, and no scenario plugin requires a stripped field), so the
od-media-generation apply still validates.
Regression at the prompt/run boundary: tests/components/HomeView.media-options
"resolves the run-facing snapshot from inputs with the deferred media settings
stripped" asserts the apply-call body that yields appliedPluginSnapshotId (the
source of snapshot.inputs) carries no deferred field while subject survives.
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>
|
||
|
|
556eb7f065 |
chore(release): bump main to 0.10.0 + clear plugin context after send (#3708 residual) (#3731)
* fix(web): clear plugin context after send * chore(release): bump version 0.9.1 -> 0.10.0 (prep main for 0.10.0 beta from main; clears the beta anti-regression gate) --------- Co-authored-by: yinjialu <2481044901@qq.com> Co-authored-by: lefarcen <ontf116@gmail.com> |
||
|
|
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
|
||
|
|
3a21392c46 |
Fix Electron composer lag and stale generation failures (#3593)
* Keep chat typing and web CSS resolution responsive Cache the normalized mention index by entity array and scan only concrete @ positions so the composer does not rescan every file/plugin/skill token on each draft update. Link the shared components package at the root importer so Turbopack/PostCSS can resolve the exported component stylesheet from the web CSS entrypoint. Constraint: Chat composer typing updates run on every keystroke in Electron, and tools-dev/Next evaluates global CSS from the workspace root. Rejected: Debouncing textarea state updates | would make text entry feel stale and would not remove the expensive synchronous parser path. Rejected: Relative-importing package source CSS from apps/web | would bypass the package export contract and hardcode package layout into the app stylesheet. Confidence: high Scope-risk: narrow Directive: Keep inline mention parsing proportional to draft mention markers, and keep package CSS imports resolvable through workspace package links. Tested: pnpm install Tested: pnpm --filter @open-design/web test -- tests/utils/inlineMentions.test.ts Tested: pnpm --filter @open-design/web typecheck Tested: pnpm --filter @open-design/web build Tested: pnpm guard Not-tested: Full web Vitest remains blocked by unrelated CSS selector tests observed before this commit. * Keep composer typing off the render path Move keystroke-time draft updates into the textarea/ref path while deferring React draft rendering, mention overlay work, picker filtering, and localStorage persistence so Electron input echo stays within frame budget. Constraint: Electron chat input was visibly lagging for plain text and mention text while the right iframe stayed responsive. Rejected: Keep the textarea fully controlled | every keystroke still synchronizes the largest ChatComposer render path. Confidence: high Scope-risk: moderate Directive: Keep prompt submission, slash commands, and mention insertion reading draftRef when draft rendering is deferred. Tested: pnpm guard; pnpm --filter @open-design/web typecheck; pnpm --filter @open-design/web build; pnpm exec vitest run -c vitest.config.ts tests/components/ChatComposer.infinite-render.test.tsx; pnpm exec vitest run -c vitest.config.ts tests/components/ChatComposer.context-pickers.test.tsx; pnpm exec vitest run -c vitest.config.ts tests/utils/inlineMentions.test.ts; Electron inspect eval plain text avg 0.03ms max 0.5ms; Electron inspect eval @ path avg 0.03ms max 0.1ms; HTTP smoke status 200 with no components CSS resolve error. Not-tested: Full web Vitest suite and Playwright UI suite. * Keep Electron chat input responsive under heavy projects Constraint: Electron project views can carry large chat/file DOM and Chromium can throttle or defer visible renderer work under tab/window visibility edge cases. Rejected: Re-rendering the composer draft on every plain keystroke | it couples textarea input to mention overlay, resize, storage, and project layout work. Confidence: medium Scope-risk: moderate Directive: Keep plain text input on the textarea/ref path; only commit React draft state immediately for mention, slash, chip, or imperative draft mutations. Tested: pnpm guard; pnpm --filter @open-design/web typecheck; pnpm exec vitest run -c vitest.config.ts tests/components/ChatComposer.infinite-render.test.tsx; pnpm --filter @open-design/desktop test; pnpm --filter @open-design/desktop typecheck; desktop inspect actual project composer with OS SendKeys. Not-tested: Push/PR remains blocked by GitHub 403 for mimicryluden on nexu-io/open-design. * Keep heavy project typing isolated from preview layout Constraint: Electron project panes can carry large DOM histories and preview frames that make textarea paint sensitive to parent layout. Rejected: Further debouncing ChatComposer input state | app-side handler costs were already low while native textarea updates still lagged. Confidence: high Scope-risk: moderate Directive: Keep the composer mounted through the fixed layer/slot pair so future layout changes do not pull typing back into the split-pane flex reflow path. Tested: pnpm --filter @open-design/web typecheck; pnpm exec vitest run -c vitest.config.ts tests/components/ChatComposer.infinite-render.test.tsx tests/components/ChatComposer.context-pickers.test.tsx; pnpm guard; pnpm --filter @open-design/web build; desktop inspect fixed-layer DOM and SendKeys probe avg beforeinput->input 1.4ms max 2.5ms Not-tested: PR publish blocked by GitHub repository permissions if remote still rejects mimicryluden * Keep stale run recovery from hiding generated previews Constraint: Completed daemon runs can outlive the in-memory run registry after a restart. Rejected: Replaying succeeded rows with empty producedFiles | It turns completed messages into failed messages when the registry is gone. Confidence: high Scope-risk: narrow Directive: Only active run statuses should enter daemon reattach recovery. Tested: vitest generation-preview; vitest ProjectView reattach restore; web typecheck; pnpm guard; web build; desktop DOM eval failureText=false iframeCount=2 Not-tested: Fresh provider generation against an external model * Keep composer contracts aligned with latest main Rebase conflict resolution restored the current composer contract while leaving the lower-risk latency fixes in separate layers. Constraint: The branch was rebased over newer workspace/session context composer contracts. Rejected: Keeping the older composer conflict side because it removed current ChatComposer props and broke web typecheck. Confidence: high Scope-risk: narrow Directive: Preserve upstream ChatComposer contracts when rebasing input-latency work. Tested: web typecheck; targeted ChatComposer, inlineMentions, ProjectView generation-preview tests; desktop window-chrome test Not-tested: Full browser interaction after fork push * Fix daemon Nix workspace symlink pruning --------- Co-authored-by: Siri-Ray <2667192167@qq.com> |
||
|
|
aea4042145 |
fix: override yauzl to 3.3.1 to resolve Electron postinstall hang on Node 24.16.0+ (#3584)
fd-slicer's custom destroy() collides with Node 24.16.0's stream lifecycle change, causing extract-zip to silently hang at 97% during Electron binary extraction. yauzl 3.x drops fd-slicer entirely. extract-zip is unmaintained and pins yauzl ^2.10.0, so the fix can only flow through a pnpm override. Refs: thejoshwolfe/yauzl#170, nodejs/node#63487 Co-authored-by: jeremeioss <jeremeibg@gmail.com> |
||
|
|
1a92175bde |
Merge origin/main into release/v0.9.0 — catch up #3379 tmp security fix + #3538
Resolves the nix/pnpm-deps.nix conflict by taking main's tmp@0.2.7 hashes (release-only deps are tools-pack/vela, outside the daemon/web FOD source filter). If CI reports a hash mismatch, refresh from the reported value. |
||
|
|
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,
|
||
|
|
13d4612f63 |
security: resolve vulnerable tmp transitive dependency (#3379)
* security: override tmp to patched version * chore: refresh nix pnpm deps hash --------- Co-authored-by: Gateway <gateway@users.noreply.github.com> Co-authored-by: a1chzt <chizblank@gmail.com> |
||
|
|
3da33f92a1 |
Harden sandbox orchestration daemon chokepoints (#3420)
* Harden sandbox orchestration chokepoints * Cover web app public copy in neutrality guard |
||
|
|
333a62cda6 |
fix: link od bin after fresh install (#2069)
* fix: link od bin after fresh install * test: lock root od bin shim path * test: cover root workspace deps in postinstall scan * chore(nix): refresh pnpm deps hash |
||
|
|
e69306ecbe | chore(release): prepare 0.9.0 | ||
|
|
df8a0faff6 |
feat(runtimes): register AMR (vela) as an ACP stdio agent (#2355)
* feat(runtimes): register AMR (vela) as an ACP stdio agent
AMR is the vela CLI's ACP runtime mode. `vela agent run --runtime opencode`
speaks ACP JSON-RPC over stdio (see vela's
`specs/current/runtime/manual-agent-run-openrouter.md`); per
`docs/new-agent-runtime-acp.md` we expose it through the same `streamFormat:
'acp-json-rpc'` transport that already powers Hermes, Devin, Kimi, etc.
The new `defs/amr.ts` is the entire wiring — `buildArgs` returns
`['agent', 'run', '--runtime', 'opencode']`, `fetchModels` reuses
`detectAcpModels`, and the fallback list seeds the OpenRouter ids vela's
e2e baseline uses. `executables.ts`/`app-config.ts`/`metadata.ts` get the
matching `VELA_BIN`/`VELA_LINK_URL`/`VELA_RUNTIME_KEY`/`VELA_OPENCODE_BIN`
allowlist + install/docs URLs, so users can configure the per-agent env in
Settings without leaking into other adapters.
Coverage: `tests/fixtures/fake-vela.mjs` is a minimal ACP stub that returns
the documented `initialize` / `session/new` / `session/set_model` /
`session/prompt` shapes; `tests/amr-acp-integration.test.ts` spawns it via
`child_process.spawn` and drives a full turn through `attachAcpSession` and
`detectAcpModels`, so the ACP transport contract for AMR is end-to-end
verified locally even before a real `vela` binary is installed.
Validated:
- pnpm guard
- pnpm typecheck (all workspace projects)
- pnpm --filter @open-design/daemon test (2881/2881)
Deferred: real OpenRouter-backed turn through a built `vela` binary —
the runtime def needs no changes for that path, only `VELA_RUNTIME_KEY`
and `VELA_LINK_URL` in env (or Settings).
* fix(runtimes/amr): pin a concrete default model and bare openai ids
End-to-end validation against a freshly-built `vela` (nexu-io/vela@main)
+ OpenRouter surfaced two contract details the first AMR runtime def
got wrong:
1. vela rejects `session/prompt` with `session/set_model must be called
before session/prompt`. attachAcpSession in apps/daemon/src/acp.ts
skips set_model whenever the picked model is the synthetic 'default'
id, so AMR's fallback list must NOT include DEFAULT_MODEL_OPTION. The
def now ships a concrete `gpt-5.4-mini` as both `fetchModels`'
default option and `fallbackModels[0]`, which makes attachAcpSession
always send a real `session/set_model` for AMR turns.
2. `vela --runtime opencode` auto-prepends `openai/` to whatever modelId
it forwards to opencode's openai provider. With OpenRouter-style ids
like `openai/gpt-5.4-mini`, opencode receives the double-prefixed
`openai/openai/gpt-5.4-mini` and replies `ProviderModelNotFoundError`.
The new fallback list ships the bare ids opencode's openai registry
actually knows about (gpt-5.4, gpt-5.4-mini, gpt-5.4-fast, etc.).
Stub + tests:
- tests/fixtures/fake-vela.mjs now enforces the set_model gate the same
way real vela does, so a regression that silently goes back to
model: 'default' would surface as a fatal error in tests instead of a
hidden production failure.
- tests/amr-acp-integration.test.ts pins both contracts: no 'default' /
no 'openai/' prefix in fallbackModels, and a negative case that
asserts session/prompt fails when no model is set.
Adds `apps/daemon/scripts/verify-amr-real-vela.mjs` — a small dev-time
runner that drives `attachAcpSession` against a real `vela` binary and
prints the daemon's chat events, so future protocol drift can be checked
against an actual OpenRouter call.
Verified locally: `vela agent run --runtime opencode` + OpenRouter
returns the prompted string ("AMR-E2E-PASS") through the full daemon
pipeline; daemon test suite stays 2883/2883.
* fix(runtimes/amr): substitute concrete model when chat run sends 'default'
A plugin-driven AMR run from the UI surfaced a real-world hole in the
prior commit:
json-rpc id 3: session/set_model must be called before session/prompt
The Default-design-router plugin (and any caller that doesn't pin a
real model) sends `model: 'default'` straight through, which the AMR
runtime def cannot accept — vela rejects `session/prompt` without
`session/set_model` and attachAcpSession skips set_model whenever
model === 'default'. Just leaving DEFAULT_MODEL_OPTION out of the
adapter's `fallbackModels` is not enough: the chat-run handler in
server.ts still forwarded 'default' verbatim.
This adds `resolveModelForAgent(def, resolved, env?)` as the
single source of truth for the substitution:
1. If the caller picked a real id, pass it through.
2. Else, if `def.defaultModelEnvVar` is set and the daemon process
env has a non-empty value for it, return that (operator escape
hatch — see below).
3. Else, if the def's `fallbackModels` does NOT contain a 'default'
id, return `fallbackModels[0].id`.
4. Else, return the original value (the historic shape — defs that
list 'default' themselves are untouched).
AMR sets `defaultModelEnvVar: 'VELA_DEFAULT_MODEL'`, so when
opencode's openai-provider registry deprecates `gpt-5.4-mini`
upstream, an operator can swap the fallback id without a code change
by exporting `VELA_DEFAULT_MODEL=gpt-5.5` before launching tools-dev
/ od. Worth noting the env var must live in the daemon's `process.env`
(Settings-UI per-agent env values only reach the spawned child, not
the daemon's resolver) — the new field's docblock spells this out.
Coverage:
- `tests/runtimes/resolve-model.test.ts` — 8 unit tests covering all
four resolver branches plus the env-override happy path / fallback /
ignore-when-user-picked-a-real-id case.
- `pnpm --filter @open-design/daemon typecheck` clean.
* chore(runtimes/amr): move AMR to the top of the base agent list
So `AMR (vela)` shows up first in the agent picker / status views,
ahead of claude / codex. Pure ordering change; no behavior delta.
* feat(amr): Sign-in / Sign-out button on the AMR Settings card
The first half of the AMR work assumed the operator would set
VELA_RUNTIME_KEY / VELA_LINK_URL on the daemon process and never
surfaced login state to users. This adds the missing UX so a fresh
install can drive the full path from Settings:
- GET /api/integrations/vela/status reads ~/.vela/config.json
for the active profile and returns { loggedIn, profile, user }
(without leaking the runtime/control keys themselves).
- POST /api/integrations/vela/login spawns `vela login` once
(409 if one is already in flight). The vela CLI opens the user's
browser to the device-authorization page itself — Open Design
only needs to kick the subprocess off.
- POST /api/integrations/vela/logout removes ~/.vela/config.json
so the next status read returns logged-out.
`AmrAgentCard` is a dedicated agent-card component for AMR because
the existing `<button>` row can't host an interactive sub-control
(nested interactive elements). It polls /status after a login click
until the daemon reports loggedIn=true (or 5 minutes elapse), and
exposes a Sign-out action on hover. Other adapters (claude, codex,
hermes, …) keep their existing `<button>` card.
i18n: 8 new keys (settings.amrLogin / Logout / LoggingIn / etc.)
added to en + zh-CN. Other locales spread `en` and inherit the
English copy until translations land.
Coverage:
- `tests/integrations/vela.test.ts` pins the config.json reader
against a tmp HOME — including the negative case where a profile
has user info but no runtimeKey (still logged-out), and the
secret-leak guard ("rt-secret-*" must not appear in the projection
payload).
- `tests/components/AmrAgentCard.test.tsx` covers all four UI
states (logged-out, logging-in, logged-in, logging-out) plus the
click-propagation invariant the divergent card was built to keep.
`pnpm --filter @open-design/daemon test` 2901 / 2901 passing.
`pnpm --filter @open-design/web test` 1719 / 1719 passing.
`pnpm typecheck` + `pnpm guard` clean.
Dev script side-effects: `apps/daemon/scripts/verify-amr-real-vela.mjs`
no longer requires both VELA_RUNTIME_KEY and VELA_LINK_URL — if
VELA_PROFILE is set, the vela CLI is allowed to resolve credentials
from `~/.vela/config.json`. Added the two AMR `.mjs` fixtures to
`scripts/guard.ts` allowlist with the executable-fixture / dev-runner
rationale.
* fix(connection-test): substitute model for AMR before attachAcpSession
The chat-run path in server.ts already routes the requested model through
`resolveModelForAgent` so AMR / vela (whose CLI demands an explicit
`session/set_model` before `session/prompt`) gets the def's first
concrete fallback id when the chat run ships `model: 'default'`.
`connectionTest.ts` was wiring `attachAcpSession({ ..., model: model ?? null })`
directly, which made the Test Connection button on the AMR Settings
card deadlock with the same `session/set_model must be called before
session/prompt` error the chat-run path already handles — surfaced as a
permanent "Testing connection…" spinner in the UI.
Reuse the same helper here so Test Connection mirrors chat-run behavior.
* test(amr): three-layer end-to-end coverage for the AMR login + turn flow
The PR up to this point shipped runtime + UI code with unit-level Vitest
coverage. This commit adds the cross-layer regression net the live demo
relied on:
1. apps/daemon/tests/integrations/vela.routes.test.ts (HTTP, Vitest)
Spins up the real daemon Express app via `startServer({port:0,...})`,
persists `agentCliEnv.amr.VELA_BIN = <fake>` into app-config.json,
and exercises every /api/integrations/vela/* endpoint against the
extended fake-vela stub:
- status reads ~/.vela/config.json under various states
- login spawns the fake, waits for config.json to appear, returns
pid + startedAt + profile
- 409 already-running guard with the stub's delay knob
- logout removes the file (idempotent)
- secrets (runtimeKey / controlKey) never leak in the projection
- login → status round-trip flips loggedIn=false → true
2. e2e/tests/amr/turn.test.ts (tools-dev orchestrated, Vitest)
Boots a namespaced daemon + web pair through `createSmokeSuite`,
inlines a self-contained fake `vela` binary that handles BOTH
`vela login` (writes ~/.vela/config.json) and
`vela agent run --runtime opencode` (ACP stdio with the
`session/set_model must precede session/prompt` gate the real binary
enforces), then drives a complete /api/runs lifecycle for
`agentId: 'amr', model: 'default'` and asserts the assistant message
captures the fake's streamed text. This is the test that would have
surfaced today's plugin-default-model regression (the `set_model
before prompt` error) at PR time instead of demo time.
3. e2e/ui/amr-login-pill.test.ts (Playwright)
Mocks /api/agents + /api/integrations/vela/{status,login,logout}
to drive the Settings AMR card through the full Sign in → Signed in
→ Sign out cycle. Pins the AmrLoginPill polling contract and the
aria-label semantics (the pill's accessible name is "Sign out" once
logged in, regardless of which label the hover-state text shows).
fake-vela.mjs extensions:
- Handles `vela login` argv by writing
~/.vela/config.json for the active VELA_PROFILE and exiting 0 —
mirrors real vela's on-disk side-effect without the device-auth
loop.
- FAKE_VELA_LOGIN_DELAY_MS knob so route tests can observe the
in-flight state of the spawn lifecycle.
- FAKE_VELA_LOGIN_USER_EMAIL / _USER_PLAN to assert the surfaced
user fields end-to-end.
Validated:
- `pnpm guard` + `pnpm typecheck` (all workspace projects)
- `pnpm --filter @open-design/daemon test`: 2998 / 2998 passing,
including the new 8-test integration suite.
- `cd e2e && pnpm test tests/amr`: 1 / 1 passing.
- `cd e2e && pnpm exec playwright test ui/amr-login-pill.test.ts`:
1 / 1 passing (6.7s).
* feat(amr): package native cli and refine login ui
* feat(amr): wire vela cli beta packaging
* docs(amr): document vela ci packaging review
* docs(amr): refine vela ci integration review
* fix(ci): refresh nix pnpm dependency hashes
* fix(pack): clean up Vela CLI packaging
* fix(pack): bundle Vela CLI support files
* fix(amr): recover login attempts from stale auth state
* test: expand AMR and automations coverage
* fix(amr): address review follow-ups
* test(web): align tasks fixtures with contracts
* fix(daemon): type wildcard route params
* fix(ci): refresh PR merge validation
* fix(amr): clear env credentials on logout
* feat(settings): inline local CLI model configuration
* fix(amr): recognize daemon env credentials
* [codex] Fix Vela companion packaging (#2979)
* Fix Vela companion packaging
* Update Nix pnpm dependency hashes
* [codex] Surface AMR account failures (#2980)
* fix: surface AMR account failures
* fix: cover AMR recovery error guidance
* chore: bump beta base version to 0.8.1 (#2990)
* Fix AMR profile and packaged runtime review issues
* Detect packaged AMR OpenCode companion tree
* feat(web): polish AMR frontend flows
* Polish AMR onboarding card
* fix: read AMR login state from dot-amr config (#3048)
* test: tighten AMR credential and packaging coverage
* test: restore AMR executable test env helper
* [codex] Fix packaged mac Dock identity and AMR label (#3076)
* Fix packaged mac sidecar Dock identity
* Rename AMR assistant label
* Fix AMR live models and dot-amr login state (#3073)
* fix: read AMR login state from dot-amr config
* fix: load live AMR models before runs
* fix: point AMR onboarding link to production wallet
* fix: address AMR model review feedback
* fix: persist live AMR model fallback
* [codex] Fix AMR link catalog model ids (#3088)
* Fix packaged mac sidecar Dock identity
* Rename AMR assistant label
* Fix AMR link catalog model ids
* Fix AMR model normalization typecheck
* Use live AMR model for default runs
* fix: polish AMR runtime settings UI
* Accelerate AMR startup defaults (#3092)
* Surface AMR insufficient balance wallet URL (#3099)
* fix(web): polish onboarding controls (#3112)
* fix(web): show CLI scan loading state
* Avoid duplicate AMR wallet recharge links (#3117)
* Avoid duplicate AMR wallet recharge links
* Use Vela CLI 0.0.3 test package
* chore(nix): refresh pnpm deps hash
* Fix AMR wallet guidance display
---------
Co-authored-by: open-design-bot[bot] <282769551+open-design-bot[bot]@users.noreply.github.com>
* chore(pack): pin Vela CLI 0.0.3-test.1 (#3127)
* chore(nix): refresh pnpm deps hash
* chore(pack): pin Vela CLI 0.0.3
* chore(nix): refresh pnpm deps hash
* fix(web): suppress AMR exit 130 fallback (#3136)
* feat(web): nudge users to hosted AMR on model/auth/quota failures (#3083)
* feat(web): nudge users to hosted AMR on model/auth/quota failures
When a non-AMR agent run fails with an auth / quota / upstream model
error, surface an inline nudge under the error pill linking to Open
Design's hosted AMR gateway (https://open-design.ai/amr). The nudge
fires `surface_view` (element=run_failed_toast) on impression and
`ui_click` (element=go_amr) on the link.
Also teach the daemon to classify CLI-agent auth/quota/upstream failures
(Claude Code, codex, ...) into specific API error codes
(AGENT_AUTH_REQUIRED / RATE_LIMITED / UPSTREAM_UNAVAILABLE) instead of
the generic AGENT_EXECUTION_FAILED, so both the error message and the
nudge key off accurate codes. AMR's own runs are excluded from the
nudge — they keep the dedicated sign-in / recharge affordances.
* feat(web): rework failed-run AMR guidance into per-case error UI
Replace the single inline nudge with a per-case failed-run experience
driven by the run's error code + agent:
- The error card is now neutral gray (was red) and always carries a
retry button; it is driven by the persisted per-message error event so
it survives a reload.
- Non-AMR agent hitting a model/auth/quota wall: a theme-color promotion
card under the error card offers "switch to AMR & retry" — switches the
run to AMR, opens Settings on the AMR card, and auto-retries once the
account signs in (ProjectView polls vela login status, independent of
the Settings pill lifecycle, with success / 5-min-timeout / unmount
exits).
- AMR agent unauthorized: clearer copy + an "authorize & retry" button.
- AMR agent out of balance: clearer copy + a "top up" button to the AMR
wallet, with manual retry.
- Settings AMR card: when opened from the nudge, it scrolls into view and
pulses, and an authorize-button coachmark (a fake hand cursor that
rises in and dismisses on hover) points at the sign-in control when not
yet authorized.
analytics: surface_view (run_failed_toast) on the promotion card and
ui_click (go_amr) on its action are retained. i18n adds chat.amrCard.*
and chat.amrError.* (en / zh-CN / zh-TW translated; other locales fall
back to en) and drops the old chat.amrErrorGuidance keys.
* fix(daemon): require status context for numeric service-failure codes
Per review on #3083: the model-service classifier matched bare HTTP
status numbers (`500`, `502`, `429`, `401`), so ordinary CLI output like
`line 500`, `read 502 bytes`, or `exit code 401` could be misclassified
as a provider outage / auth wall and wrongly surface the AMR nudge. Now
a status number only counts when it carries explicit context (`HTTP 500`,
`status 503`, `code: 401`, `502 Bad Gateway`); textual provider phrases
(overloaded, bad gateway, service unavailable, rate limit, …) are
unchanged. Adds fixtures proving unrelated numeric output stays null.
* fix(web): keep error pill for failed runs ChatPane's card doesn't cover
Per review on #3083: the per-message gray error pill was suppressed for
every persisted error status event, but ChatPane only renders the
replacement top-level error card for `retryableAssistantMessage` (the
last failed assistant). So a failed turn that is no longer last (after a
follow-up) or an older failed run in history showed neither the pill nor
the card — its error detail vanished, undercutting reload/history
survival. ChatPane now passes `errorCardOwnerId` (the assistant id whose
error the card represents); AssistantMessage suppresses only that one
pill and keeps rendering StatusPill for all other error events.
* fix(daemon): don't treat a process exit code as an HTTP status
Follow-up to review on #3083: the status-context helper accepted a bare
`code` prefix, so `exit code 401` / `process exited with code 429` still
matched and got classified as AGENT_AUTH_REQUIRED / RATE_LIMITED (the
very `exit code 401` case the comment calls out as noise). `code` now
only counts when qualified (`status code` / `error code` / `response
code`) or punctuation-bound (`code: 401`); bare `exit code N` no longer
matches. Adds fixtures for exit-code lines returning null.
* chore(web): translate AMR card / error keys for 16 remaining locales
PR #3083 added 10 new `chat.amrCard.*` / `chat.amrError.*` keys but only
provided en/zh-CN/zh-TW translations; the other 16 locales fell back to
English. Translate the card title/body, three chips, primary CTA, and
the AMR self-error (auth / balance) messages and buttons for ar, de,
es-ES, fa, fr, hu, id, it, ja, ko, pl, pt-BR, ru, th, tr, uk.
* fix(amr): address review feedback on #2355
Targeted fixes for the unresolved review threads on #2355. Each fix
includes / updates a focused test.
- runtimes/executables.ts: `packagedVelaOpenCodeCompanionTree` now
verifies the inner `opencode` executable exists + is runnable, not
just the directory. This closes the false-positive availability path
that let `detectAgents()` surface AMR as available even when the
packaged companion was empty / partially copied (mrcfps, 4 threads).
- runtimes/executables.ts: `resolveAmrOpenCodeExecutable` now prefers
the bundled `<OD_RESOURCE_ROOT>/bin/libexec/opencode/opencode` over a
stale `opencode` on the user's PATH, so packaged AMR builds can't be
hijacked by a global installation.
- web/EntryShell.tsx: when the Local CLI scan returns an available
agent and the previously-selected agent is AMR, switch the selection
to the first available local agent so the runtime and persisted
agent agree before Continue.
- server.ts (model-probe branch): for AMR, check `readVelaLoginStatus`
BEFORE rejecting on an empty live-model catalog — a signed-out user
was getting `AMR_MODEL_UNAVAILABLE` ("choose a model") instead of
the correct `AMR_AUTH_REQUIRED` (sign-in affordance).
- server.ts (default model fallback): if the user asked for the AMR
agent default and the cached id is no longer in the FRESH catalog,
fall back to `liveModels[0]` from the probe instead of rejecting the
run as `AMR_MODEL_UNAVAILABLE`.
- integrations/vela.ts: route `vela login` through
`createCommandInvocation` so an npm/Node-style `vela.cmd` / `.bat`
shim on Windows gets the correct `cmd.exe /d /s /c …` wrapping with
verbatim args (matches `execAgentFile` / chat-run spawning).
- tools/pack/src/linux.ts: in containerized Linux builds, bind-mount
the host directory of `OPEN_DESIGN_VELA_CLI_BIN` and rewrite the env
to the container-side path. The host path was being passed in as-is
even though the default container only mounts /project, /tools-pack
and cache/home — `copyOptionalVelaCliBinary` saw a missing path.
Deferred (out of scope for this PR):
- `od amr status/login/logout/cancel` CLI subcommands (AGENTS.md
UI/CLI dual-track rule, server.ts:5763) — sizable surface; tracked
for a separate focused PR.
- Strict `--require-vela-cli` for Windows + mac-x64 beta builds:
prematurely blocked — `@powerformer/vela-cli` only publishes the
`darwin-arm64` platform binary today; adding the flag elsewhere
would fail the builds. Revisit once win/x64/linux binaries ship.
* fix(amr): hoist sendAmrAccountFailure above the AMR catalog preflight (TDZ)
The new signed-out AMR branch in the catalog preflight at server.ts:10875
calls `sendAmrAccountFailure(...)` to emit AMR_AUTH_REQUIRED, but the
const declaration sat ~100 lines below at the outer function scope. Because
`const` is TDZ-aware, that branch would have thrown `ReferenceError:
Cannot access 'sendAmrAccountFailure' before initialization` for the
exact users it tries to help — defeating the original intent.
Hoist the helper to just above the AMR preflight block so it's available
to every AMR code path in this function. Behavior elsewhere is unchanged.
Also rerun the daemon test suite: `launch.test.ts > resolveAgentLaunch
uses packaged built-in Vela for AMR` was creating the
`<resourceRoot>/bin/libexec/opencode/` companion *directory* only, but
this PR's earlier tightening of `packagedVelaOpenCodeCompanionTree`
also requires the inner `opencode` executable. Add it to that fixture
to match the new contract; the test was a sibling of the executables /
env-and-detection fixtures already updated in
|
||
|
|
d5659d82d4 |
chore(nix): streamline pnpm deps hash maintenance (#2919)
* chore(nix): streamline pnpm deps hash maintenance Generated-By: looper 0.9.0 (runner=worker, agent=opencode) * fix(ci): satisfy actionlint in nix hash autofix Generated-By: looper 0.9.0 (runner=fixer, agent=opencode) * fix(ci): allow nix hash autofix on fork PRs Generated-By: looper 0.9.0 (runner=fixer, agent=opencode) * fix(ci): follow up nix hash review Generated-By: looper 0.9.0 (runner=fixer, agent=opencode) * fix(ci): tolerate nix hash bot token failures Generated-By: looper 0.9.0 (runner=fixer, agent=opencode) |
||
|
|
128b62f863 |
chore: patch qs advisory (#2833)
* chore: patch qs advisory * chore: update daemon pnpm deps hash |
||
|
|
34165ff189 | chore: retire tools-pr (#2867) | ||
|
|
c14baf07d3 |
Merge origin/main into release/v0.8.0
PR #2461 sync prep — resolves 14 conflicts merging 84 main-side commits on top of 58 release-side commits accumulated during the 0.8.0 cycle. Resolution summary: Take main (theirs) where main carried deliberate forward progress: - apps/web/src/components/PluginCard.tsx — 7 hunks, i18n migration: hardcoded English aria-labels/titles replaced with t() calls keyed on pluginCard.* (all 8 keys verified present in en.ts). - apps/web/src/components/TasksView.tsx — 1 hunk, source-ingestion feature: sortedRoutines (newest-first), sourceIngestionTemplates, patchSourceForm, submitSourceIngestion. activeCount/pausedCount semantics preserved (now keyed on sortedRoutines, count unchanged). - e2e/ui/app.test.ts — new node:fs/promises + tmpdir + path + @/timeouts imports needed by main-side test helpers. - e2e/ui/settings-local-cli-codex-fallback.test.ts — menu-dismissal helper block added by main. Keep both sides where each added a different field to the same object literal: - apps/web/src/components/ProjectView.tsx (locale + analyticsHints spread). - apps/web/src/components/DesignSystemFlow.tsx (locale + analyticsHints). Take release (ours) where release carried deliberate work that ships 0.8.0: - CHANGELOG.md — release-side 0.8.0 entry + PR link refs; main's Unreleased section was the same body of work, now finalized. - apps/landing-page/public/{apple-touch-icon,favicon}.png + apps/web/public/app-icon.svg — release-side visual refresh assets consistent with 0.8.0 stable ship. - tools/pack/src/linux.ts — packageVersion const required by line 466; taking main's empty line would build-error. - e2e/ui/project-management-flows.test.ts + e2e/ui/settings-api-protocol.test.ts + e2e/ui/settings-memory-routines.test.ts — release-side release-smoke hardening (shangxinyu1 + PerishFire) takes precedence on overlap. Closes-issue / unblocks: PR #2461 sync release/v0.8.0 → main. |
||
|
|
6592d638ce |
ci: gate fork PR workflow auto-approval (#2683)
* ci: gate fork PR workflow auto-approval * ci: rename fork PR approval workflow * ci: normalize fork workflow paths Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): match action_required workflow runs Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): denylist tool config paths Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): retry action_required workflow lookup Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): restrict fork workflow approvals to target PR Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): keep polling fork workflow approvals Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): revalidate fork workflow approvals before approving Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): poll longer for first fork approval run Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): make fork approval poll budget configurable Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): drop stale fork approval runs Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): deny dotted tsconfig variants in fork approvals Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): run fork approval regression in guard Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): refresh Nix pnpm deps hash Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * test(web): mock useI18n in reattach restore test Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): accept status-only fork approvals Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): rerun fork approval on retarget Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): ignore base tip churn in PR association Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): broaden pending approval run fetch Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): skip non-retarget fork approval edits Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): checkout visual comment workflow head Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): paginate workflow approval run lookup Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): harden fork workflow follow-ups Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): honor full post-appearance settling window Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) * fix(ci): validate manual visual comment checkout Generated-By: looper 0.0.0-dev (runner=fixer, agent=opencode) |
||
|
|
aa0616062d |
refactor(daemon): introduce HTTP Request Adapter + typed Deps (#2636)
* refactor(daemon): introduce HTTP Request Adapter + typed Deps (proof on active-context-routes)
Adds a typed HTTP boundary Adapter under apps/daemon/src/http/ that replaces
the untyped ServerContext service-locator pattern (30+ fields, mostly any)
for route handlers. Routes become pure (input, deps) -> Result<output>
functions, unit-testable without Express or supertest.
Six new modules under apps/daemon/src/http/:
- types.ts Result<T,E>, ok(), err(), JsonRouteSpec, Handler,
RouteInputContext, HttpMethod, InputParser
- parse.ts rawInput(req), validationError(message, issues?)
- response.ts sendJson(), sendApiError(), statusForError() +
ERROR_STATUS_BY_CODE map
- origin-guard.ts guardSameOrigin(req, origin) wrapping isLocalSameOrigin
as a Result
- adapter.ts defineJsonRoute(), mountJsonRoute() (only place that
knows about req/res)
- index.ts barrel
active-context-routes.ts migrated as proof of pattern. parsePostActive(),
handlePostActive(), handleGetActive() are now pure functions; postActiveRoute
and getActiveRoute are exported route specs. The wire signature
registerActiveContextRoutes(app, ctx) is preserved so server.ts is untouched.
Spec at specs/current/daemon-http-adapter.md captures the strangler migration
order for the remaining route files (mcp-routes, chat-routes, artifact
routes, etc.) and a StreamRoute follow-up where the Run Orchestrator lands.
Wire-format note: cross-origin response moves from the legacy
{ error: 'cross-origin request rejected' } shape to the structured
{ error: { code: 'FORBIDDEN', message: ... } } shape. Backwards-compatible
via the existing CompatibleErrorResponse = ApiErrorResponse | LegacyErrorResponse
union in @open-design/contracts.
Validation:
- pnpm install (post-rebase, exit 0)
- pnpm --filter @open-design/daemon typecheck (both tsconfig.json and
tsconfig.tests.json silent => pass)
- pnpm --filter @open-design/daemon test: 15 new tests pass
(tests/http/adapter.test.ts + tests/active-context-routes.test.ts).
84 pre-existing failures across 23 files are unchanged and unrelated
to this PR (Windows symlink / short-name / colon-in-filename, upstream
behavior drift, missing plugin marketplace fixtures, and a freshly-
added tools-connectors-cli suite of 38 failures that landed during
the rebase).
Sharpens W4/W5 of specs/current/maintainability-roadmap.md and unlocks
W6 (Run Orchestrator).
* chore: add core-js, electron-winstaller, protobufjs, sharp to pnpm.onlyBuiltDependencies
|
||
|
|
10192dcc52 |
fix(ci): catch nix hash drift before merge (#2530)
* fix(ci): catch nix hash drift before merge * fix(nix): add pnpm hash refresh helper * chore(nix): drop redundant hash alias * fix(nix): raise update-hash output buffer Generated-By: looper 0.8.1 (runner=fixer, agent=opencode) * fix(nix): handle current pnpm deps hash Generated-By: looper 0.8.1 (runner=fixer, agent=opencode) * fix(nix): reject non-mismatch hash updates Generated-By: looper 0.8.1 (runner=fixer, agent=opencode) |
||
|
|
50a4dc8a62 | Merge origin/main into release/v0.8.0 | ||
|
|
85276df284 |
chore(deps): patch security override and patch bumps (#2306)
- Add pnpm override: protobufjs 8.4.0 (CVE-2026-45740, GHSA-jggg-4jg4-v7c6) - Bump postcss 8.5.14 -> 8.5.15 in apps/web (and root override) - Bump tsx 4.22.2 -> 4.22.3 across all workspace packages Co-authored-by: Patrick A <259201958+eefynet@users.noreply.github.com> |
||
|
|
722ddfa235 |
Merge origin/main into release/v0.8.0
Conflicts resolved by taking origin/main on both files. Root cause: main's PR #2460 (fix(landing): align logo.webp with brand icon) changed HomeHero.tsx's .home-hero__brand-mark to render <img src=/app-icon.svg> instead of an inlined <HeroBrandIcon /> SVG, and bundled the matching CSS (26px round badge with bg-panel + border + padding 2px) plus a gap/font-size tune. The release-side visual-refresh CSS still targeted the SVG layout (38px square, transparent, inset SVG selector). Keeping release's CSS would leave main's <img> unstyled. - apps/web/src/styles/home/home-hero.css three blocks, all taken from main: .home-hero__brand gap 8px, .home-hero__brand-mark redesigned for <img> child, .home-hero__brand-name font-size 16px. - apps/web/src/index.css two blocks, both taken from main: workspace tab close column 22px and .workspace-tab__close 18x18 (paired tune-down of tab UI spacing). |
||
|
|
8193981511 |
Keep PR 2400 changes without folder pickers (#2462)
* feat(daemon): add project working directory management and editor hand-off functionality - Introduced new flags for project commands to manage working directories, including `--working-dir` and `--dir`. - Implemented API routes for listing available editors and opening projects in selected editors. - Added a hand-off button in the ChatPane header to facilitate opening project folders in local applications. - Enhanced the HomeHero component to include working directory and design system settings, improving user experience in project creation. - Created HomeHeroSettingsChips component for inline management of working directory and design system selection. * feat(chat): implement voice transcription proxy and enhance UI components - Added a new API route for voice transcription using OpenAI's `/audio/transcriptions` endpoint, allowing users to send audio blobs directly for transcription. - Integrated multer for handling audio file uploads in memory, ensuring efficient processing without disk storage. - Updated the HomeHero component to include example prompt suggestions for plugins, enhancing user interaction. - Introduced the EditorIcon component to visually represent different editors in the hand-off menu, improving the user experience. - Refined the HandoffButton component to utilize the new EditorIcon, providing a more cohesive interface for selecting editors. - Enhanced CSS styles for various components to improve layout and responsiveness, including adjustments to tab and button sizes for better usability. * style(workspace-shell): enhance layout and overflow handling - Updated CSS for .workspace-shell to ensure full viewport width and height, with proper overflow management. - Adjusted grid layout to prevent content overflow and maintain responsiveness. - Modified styles for .workspace-tabs-chrome to improve width handling and prevent overflow issues. * refactor(chat): remove voice transcription proxy and related components - Deleted the voice transcription proxy implementation, including the associated API route and multer configuration. - Removed the MicButton component from the ChatComposer and HomeHero components to streamline the UI. - Updated HomeHero to include example suggestions without the voice input functionality. - Adjusted CSS styles for various components to maintain layout consistency after the removal of the MicButton. * feat(daemon): implement minting of HMAC tokens for working directory management - Added a new function `mintImportTokenFromCurrentSecret` to generate HMAC tokens bound to a specified base directory, enhancing security for working directory operations. - Updated the `desktop-auth.ts` file to include the new token minting functionality, which returns structured errors when the desktop auth secret is cleared. - Introduced new IPC message types for minting import tokens in the sidecar protocol, allowing seamless integration with the daemon's working directory management. - Enhanced the `WorkingDirPill` component to utilize the new token minting flow for secure directory selection in desktop builds. - Updated CSS styles for the HomeHero component to accommodate new example suggestion features and maintain layout consistency. * fix(HomeView): import HOME_HERO_CHIPS constant for improved chip management - Updated the HomeView component to import the HOME_HERO_CHIPS constant from the chips module, enhancing the management of hero chips within the component. * feat(daemon): implement mintImportTokenViaSidecar for secure working directory management - Introduced the `mintImportTokenViaSidecar` function to facilitate the minting of HMAC tokens for desktop-import operations via the daemon's sidecar IPC. This allows CLI commands to bypass authentication when the desktop-auth gate is active. - Updated the CLI to utilize the new token minting function when setting the working directory, ensuring secure access to trust-gated API endpoints. - Enhanced the sidecar server to handle minting requests and return structured error messages for improved user feedback. - Added tests to validate the new token minting functionality and its integration with the working directory management process. - Refactored related components to support the new token flow, improving overall security and user experience. * feat(HomeHero): enhance UI components and styles for improved user experience - Updated HomeHero component to replace active dot indicators with Plug icons for better visual representation of active plugins. - Adjusted CSS styles for various elements, including padding and dimensions, to enhance layout consistency and responsiveness. - Introduced new styles for active type icons and improved hover effects for buttons. - Updated HomeHeroSettingsChips to change button titles and icons for clarity. - Added tests to ensure proper rendering and functionality of updated components. * feat(ProjectDesignSystemPicker): enhance design system selection with preview functionality - Updated the ProjectDesignSystemPicker component to include a preview feature for design systems, allowing users to see a preview of the selected design system. - Implemented hover functionality to update the preview based on the hovered design system. - Added fullscreen preview capability for a more immersive experience. - Enhanced CSS styles for the design system picker to improve layout and responsiveness. - Introduced tests to validate the new preview functionality and ensure proper interaction within the component. * feat: refactor project metadata handling and enhance design system picker - Updated the default scenario plugin ID retrieval to use project metadata, improving the logic for determining the appropriate plugin based on project intent. - Enhanced the ProjectDesignSystemPicker and related components to support localized design system summaries and categories, improving user experience. - Introduced new translations for working directory and design system picker components, ensuring better accessibility and usability across different locales. - Added a new 'live-artifact' project type to the HomeHero chips, expanding the functionality for users creating refreshable artifacts. - Updated tests to validate the new project metadata handling and design system picker functionalities. * feat: enhance localization and styling for design system components - Added French translations for working directory and design system picker components, improving accessibility for French-speaking users. - Updated CSS styles for the pet task item to ensure consistent padding and layout. - Introduced a new test suite for HomeHeroSettingsChips to validate localization and design system selection functionality. - Enhanced ProjectDesignSystemPicker tests to ensure proper localization and interaction with design system categories. * fix: update .gitignore to include all claude-sessions directories and remove specific session files - Modified .gitignore to ensure all claude-sessions directories are ignored by using a wildcard pattern. - Deleted two specific claude-sessions markdown files to clean up unnecessary session data. * fix: repair home automation ci regressions * fix: stabilize artifact consistency e2e * Remove folder picker changes from PR 2400 --------- Co-authored-by: pftom <1043269994@qq.com> Co-authored-by: qiongyu1999 <2694684348@qq.com> |
||
|
|
aedbb9dbe4 |
release: Open Design 0.8.0
Bumps 14 workspace package.json files from 0.7.0 to 0.8.0:
- root, apps/{web,daemon,desktop,landing-page}
- packages/{contracts,host,platform,sidecar,sidecar-proto}
- tools/{dev,pack,pr}, e2e
apps/packaged was already at 0.8.0 from the preview lane.
Independently versioned packages keep their own tracks.
Adds CHANGELOG [0.8.0] - 2026-05-20 entry covering the
305 PRs merged since 0.7.0 by 75 contributors:
- Plugin engine rebuild + Plugin Registry surface
- Headless by default (desktop is thin wrapper around CLI)
- Critique Theater Phases 9 through 16
- 149 design systems with structured tokens.css
- Italian locale + CJK font fallback
- Leonardo.ai, ElevenLabs, SenseAudio providers
- Windows packaged auto-update
- Visual refresh + Quick-brief discovery overhaul
- PostHog v2 analytics
- Manual edit UX overhaul
|
||
|
|
bd48c597b0 |
chore: pin dependency versions and harden CI caches (#2189)
* chore: pin dependency versions * ci: enforce pinned dependency specs * ci: fix pnpm executable invocation |
||
|
|
99b42726b8 | Simplify CI PR gate (#2183) | ||
|
|
4424f08be0 |
[codex] Add packaged desktop auto-update (#1375)
* Add packaged desktop auto-update * Handle counted beta nightly update versions * Refresh desktop auto-update branch for main * Serialize desktop updater operations * Refresh auto-update branch for packaged paths |
||
|
|
3944ef34b8 |
feat(scripts): add informational i18n coverage report (#1896)
Adds `scripts/i18n-coverage-report.ts` (wired via `pnpm i18n:coverage`) that reports per-locale key-coverage drift against English. The output looks like: Locale (key total = 1578 on en) en English keys=1578 missing= 0 ... zh-CN 简体中文 keys=1578 missing= 0 coverage=100% th ภาษาไทย keys=1261 missing= 317 coverage=80% ... Why this is useful right now: - The existing `scripts/i18n-check.ts` validates *structural* consistency (locale registration, README switcher alignment, core doc link references) and exits non-zero on failure. It does not surface content-coverage drift. - The test suite enforces strict English-parity only for Indonesian (`id`) — other locales pass CI even when an English key was added without a matching translation. Today the average locale is missing ~140–300 keys vs English on `main`. This script is purely informational — exit code stays 0. It gives contributors and release managers a fast way to see which locale needs translation work without breaking PRs until the locale catches up. Issue #1894 covers the policy question of *whether* strict enforcement should extend beyond Indonesian (e.g., to a tier-1 locale set); this script is the substrate for that policy conversation, not a substitute for it. Refs #1894. Validation: - `pnpm i18n:coverage` runs end-to-end against the 19 locale files under `apps/web/src/i18n/locales/`, exit 0. - `pnpm guard` green. - `pnpm exec tsc -p scripts/tsconfig.json --noEmit` green. Co-authored-by: nicejames <nicejames@gmail.com> |
||
|
|
5172e37217 |
Merge origin/main into release/v0.7.0 to prepare merge-back PR
Resolves 7 conflicts via hybrid strategy: - apps/web/src/components/EntryView.tsx: take main (Discord+X pills are forward feature) - apps/web/src/components/Icon.tsx: take main (switch-case refactor) - apps/web/src/components/NewProjectPanel.tsx: take release (preserve #1514 dropdown UX validated in 0.7.0 acceptance) - apps/web/src/index.css: take main (project-target-platforms / instructions chip styles) - apps/web/tests/components/FileViewer.inspect-empty-hint.test.tsx: accept main's deletion - nix/package-daemon.nix, nix/package-web.nix: take main pnpmDepsHash Non-conflicting hunks from #1519 (AppChromeHeader), #1428 (PostHog analytics call sites), and #1540 (release light background) are preserved via auto-merge. |
||
|
|
f621dbbfea | feat(web): Add Tailwind foundation (#1388) | ||
|
|
2a0ebea50b |
release: Open Design 0.7.0
- bump 14 monorepo package.json files to 0.7.0 (root + apps/{web,daemon,desktop,packaged,landing-page} + packages/{contracts,platform,sidecar,sidecar-proto} + tools/{dev,pack,pr} + e2e); apps/packaged was already at 0.6.1 from beta lane, all others at 0.6.0
- add CHANGELOG.md [0.7.0] - 2026-05-12 entry covering 97 merged PRs since 0.6.0:
- Critique Theater: Phase 7 web client state machine (#1307) + Phase 6.2 daemon artifact extraction (#1085)
- Web/UI: thumbs-up/down feedback widget (#1308), Cmd+, opens Settings (#1173), Finalize design package + Continue in CLI (#974), fetch models button for BYOK (#1034), provider models alphabetical sort (#1097), collapsible MCP JSON field-mapping (#1136), design file rename (#894)
- Daemon: auto-memory store with chat-protocol-aware extraction (#999), install/uninstall skills & design systems (#1003), HTTP 206 range requests for video/audio (#1105), scheduled routines (#1033), agent runtime + route registration refactor (#1063, #1043)
- HyperFrames: HTML-in-Canvas across web + skills (#866)
- Skills/design systems: generic skills + design-templates split + finalize-design API (#955), agent-browser skill (#1284), WeChat design system + login-flow skill (#1083), hud/loom/trading-terminal design systems (#1069), release-notes-one-pager skill (#873), tokens.css schema (#1231)
- Packaging: macOS Intel (x64) build (#759), official Nix flake (#402), beta packaging cache (#1095)
- Maintainer ops: tools-pr PR-duty workspace (#1259), MAINTAINERS.md (#1290), contributor card bot (#932), PR→issue linking discipline (#1263)
- Changed: conversation run isolation (#1271), default English i18n fallback (#1270), Codex CLI exit diagnostics / empty-response handling / path fallback (#1267, #1244, #1205)
- Fixed: ~30 web + desktop + daemon + packaging bugfixes
- Internal: nightly UI/desktop regression coverage (#1256), e2e/release report hardening (#1140), entry/settings automation (#954)
- catch up [Unreleased] compare link to v0.7.0 and add missing [0.6.0] release link
- add 97 PR footnote refs ([#402]..[#1330])
Verified locally: pnpm install + pre-build contracts/daemon/desktop dist + pnpm typecheck (exit 0 across all 14 packages on Node 22.22 with engine-warning).
Release workflow validation runs after merge via release-stable.
|
||
|
|
8c0fb8dc01 |
feat(tools-pr): add maintainer PR-duty workspace (#1259)
* feat(tools-pr): add maintainer PR-duty workspace
Adds `tools/pr` as the maintainer-only control plane for PR-duty work on
this repo. Thin `gh` wrapper that encodes repo-specific knowledge:
review lanes, forbidden surfaces, lane-specific checklists, validation
command derivation from touched packages.
Subcommands:
- `list` — triage open queue by lane and review-state bucket.
- `view <num>` — agent-friendly review brief for a single PR.
- `classify [num]` — emit script-level tags for one PR or the whole
open queue; full-queue JSON output lands under `.tmp/tools-pr/classify/`
with rate-limit telemetry per run.
- `assignment` — assigner-perspective view of PR ownership, idle time,
and blockers (derived from existing tags; no new judgments).
Tag dictionary (13 tags) covers: bot-only-approval, needs-rebase,
forbidden-surface, unlabeled, duplicate-title, non-ascii-slug,
maintainer-edits-disabled, org-member, unresolved-changes-requested,
stale-approval, and three awaiting-* timing tags. Each rule is
expressible as one factual sentence over `gh` data + repo paths — see
`tools/pr/AGENTS.md` for the full dictionary plus precision rules.
Templates in `tools/pr/templates/*.md` are aesthetic references for
recurring maintainer comments (duplicate-title ask, awaiting-author
nudge, agent-review brief shape). `templates/examples/` holds
frozen-in-time agent-review snapshots for three PR shapes.
Infrastructure:
- `gh()` wraps `execFile` with minimum-touch retry (2 attempts at 1s + 2s
backoff) on transient 5xx / network errors. Persistent failures still
surface — retry is anti-jitter, not an exponential-backoff resilience
layer.
- Heavy chunks (`reviews`, `comments`, `commits`, assignment timelines)
use cursor-paginated `gh api graphql` via `fetchPaginatedPrList` to
stay under GitHub's GraphQL server-side timeout. Light chunks stay on
`gh pr list --json`.
- `fetchOrgMembers` cached per process via `gh api orgs/<owner>/members
--paginate`.
Wiring:
- Root `package.json` adds `pnpm tools-pr` to the allowed root entry
points.
- `scripts/postinstall.mjs` builds `tools/pr` alongside other workspace
packages.
- `scripts/guard.ts` allowlists `tools/pr/bin/tools-pr.mjs` and
`tools/pr/esbuild.config.mjs`, and adds `pr/` to the `tools/` top-level
layout allowlist.
- Root `AGENTS.md` and `tools/AGENTS.md` document the new command
surface, root-command-boundary update, and per-tool ownership.
* docs(agents): brief tools-pr in root AGENTS.md, link to tools/pr/AGENTS.md
Adds a `PR-duty tooling` section to the root AGENTS.md summarising what
`pnpm tools-pr` is, listing the four common subcommands (list / view /
classify / assignment), and pointing readers to `tools/pr/AGENTS.md` for
the full tag dictionary, operational playbook, templates, and design
rules. The section keeps root-level guidance to high-level orientation
while details stay local to the tool's own AGENTS.md.
* fix(tools-pr): drop overly broad touches-root-package.json forbidden hit
`deriveForbidden` was flagging any change to root `package.json` as a
forbidden-surface hit, but AGENTS.md §Root command boundary only forbids
specific *lifecycle* aliases (pnpm dev / test / build / daemon / preview
/ start) — tools-control-plane entrypoints like `pnpm tools-pr` are
explicitly allowed. Distinguishing "forbidden alias" from "allowed
entry" requires reading the diff content, which is `pnpm guard`'s job
rather than a path-derived classify tag.
Dogfooded on this branch's own PR (#1259), which added the `pnpm
tools-pr` script and was incorrectly flagged. Removing the hit aligns
the `forbidden-surface` tag with what tools-pr can mechanically detect
from file paths alone (apps/nextjs/, packages/shared/).
* fix(tools-pr): paginate commits fetch, recognise ready-to-merge, escape title-index separator
Three review follow-ups on #1259, all factual fixes:
- `fetchOpenPrCommits` now uses `fetchPaginatedPrList` instead of a
one-shot `pullRequests(first: $first)` query. GitHub GraphQL caps
connection page size at 100, so the previous implementation would
fail at runtime when callers passed `--limit > 100`. The paginated
path makes the commits fetch consistent with the other heavy chunks
(reviews, comments, assignment timelines) and removes the artificial
ceiling entirely. The `limit` parameter is dropped from
`fetchOpenPrCommits`; the CLI `--limit` continues to bound the
`gh pr list --json` chunks.
- `deriveStatus` in `assignment.ts` now reads `facts.reviewDecision`
and `facts.mergeStateStatus`. When the PR is `APPROVED` with merge
state `CLEAN` or `UNSTABLE` and carries no blockers, status renders
as `ready to merge` instead of falling through to `in review`. The
assignment view loses its main triage signal without this — a clean
human-approved PR rendered identical to a REVIEW_REQUIRED one.
- `tags.ts:tagDuplicateTitle` and `tags.ts:buildContext` both
constructed the title-index key with a literal NUL byte between
author and title, which made the file appear as binary in `git diff`
/ review tooling. Replaced the literal byte with a Unicode escape
sequence in source; the runtime string value is identical, the
source stays plain text and round-trips through review tooling
cleanly.
* fix(tools-pr): raise default --limit to 1000 to cover the live open queue
mrcfps flagged that `tools-pr list` (and `classify --all`, `assignment`)
defaults to `--limit 100`, which silently drops every PR past the first
100 in the open queue. The repo currently sits at 104 open PRs, so the
out-of-the-box run was already omitting four PRs.
Raise the default to 1000 in `list.ts`, `classify.ts`, and `assignment.ts`,
and remove the now-pointless 200 ceiling — `gh pr list --limit N` paginates
internally, so a high cap is cheap. Users can still pass `--limit <small>`
for a truncated preview. CLI help text on the three subcommands updated to
match.
* fix(web): pass designTemplates to ProjectView render helper
#955 made `designTemplates` a required Prop on ProjectView, but the test
helper added in #1244 (`renderProjectView` in
`ProjectView.api-empty-response.test.tsx`) was never updated. The two
PRs landed on main without conflicting, leaving `apps/web` typecheck red
for every PR that rebases past
|
||
|
|
b5eb8c1647 |
feat: generic skills + split skills/design-templates + finalize-design API (#955)
* feat: general-purpose skills with @-mention composition and user import
Lift skills from "one mode-bound skill per project" to a generic capability
the user can compose per turn:
- Daemon: scan multiple skill roots (user-skills under runtime data, then
the bundled `skills/`); user-imported skills can shadow built-ins by id.
- New `POST /api/skills/import` and `DELETE /api/skills/:id` endpoints,
with CONFLICT/BAD_REQUEST/NOT_FOUND error codes and built-in delete
protection.
- ChatRequest gains `skillIds: string[]`; the chat run concatenates each
picked skill's body (and merges craftRequires) into the system prompt
for that turn only — the project's persistent `skillId` is untouched.
- Web composer: `@` popover now lists skills alongside project files;
picks render as removable chips above the textarea and ride along with
the request as `skillIds`.
- Settings → Library: import form (name/description/triggers/body),
per-card delete for user skills, "user" origin badge.
* chore(web): drop welcome pet teaser + add ds→prompt-template mapping util
- SettingsDialog: remove the inline pet adoption teaser from the welcome
panel so the first-run modal stays focused on configuration.
- New `inferPromptTemplateCategoriesForDs(ds)` helper that maps a design
system's authored metadata to prompt-template gallery categories.
Imported by the design-system gallery wiring on a sibling branch; no
callers in this branch yet.
* feat: split skills/design-templates and add finalize-design API
Phase 0 of the skills/design-templates refactor (specs/current/
skills-and-design-templates.md):
- Move ~104 rendering catalogue entries from skills/ to design-templates/
and keep skills/ for the small set of functional skills that *do work*
on user input (utilities, briefs, packagers).
- Add design-templates/AGENTS.md and skills/AGENTS.md describing the
contract, and a brand-agnostic craft/ surface for opt-in craft rules.
- Daemon: add DESIGN_TEMPLATES_DIR / USER_DESIGN_TEMPLATES_DIR roots and
an /api/design-templates surface mirroring /api/skills. Asset/example
routes still span both registries so existing srcdoc URLs keep
resolving across the rename.
- Web: split LibrarySection into SkillsSection + DesignSystemsSection,
rename the EntryView "Examples" tab to "Templates", and update locales
+ the New-project picker accordingly.
Adds the finalize-design endpoint:
- New apps/daemon/src/finalize-design.ts and packages/contracts/src/api/
finalize.ts — one-shot synthesis of a project's transcript + active
design system + current artifact into <projectDir>/DESIGN.md via the
Anthropic Messages API. Per-project .finalize.lock mirrors the
transcript-export hygiene from PR #493; provider credentials are not
persisted by the daemon.
Other supporting changes:
- README + AGENTS.md updates to document the new directory split and
craft/ surface, plus i18n strings across 13 locales.
- Test refactors and new coverage (finalize-design, runs, sidecar
server, plus refreshed daemon integration tests).
- .gitignore: scope the *.exe ignore to /OpenDesign.exe so legitimate
vendor binaries are no longer hidden.
* fix(merge): move clinical-case-report to design-templates/
Origin/main added the clinical-case-report skill under skills/ before
the skills/design-templates split landed. Its od.mode is prototype, so
per specs/current/skills-and-design-templates.md it is a design template
and belongs alongside the other rendering catalogue entries — not under
the slimmed-down functional skills/ root. Moving it keeps the EntryView
Templates tab consistent with origin/main's intent.
* feat(skills): curated design/creative catalogue + collapsible Settings rows
Seed ~100 curated design/creative skill stubs under skills/ sourced from
awesome-claude-skills (ComposioHQ) and awesome-agent-skills (VoltAgent).
Each stub carries an od.category tag so the new filter pill row in
Settings -> Skills can group them. The seed script
(scripts/seed-curated-design-skills.ts, pnpm seed:curated-design-skills)
is idempotent: it only creates folders that don't already exist, so
hand-edited stubs are never overwritten.
- Daemon: parse and surface od.category on SkillInfo with a strict slug
normaliser; mirror the field on SkillSummary in @open-design/contracts.
Category is purely a UI hint — system-prompt composition is unchanged.
- Web: rewrite SkillsSection from a left-list / right-detail grid into a
vertical stack of collapsible rows mirroring the External MCP panel
(header always visible with name + mode/source/category pills + per-row
enable toggle; SKILL.md preview, file tree and inline edit form expand
on demand). Add a Category filter row above the list. Reorder Settings
nav so Skills + External MCP sit above the Composio/MCP cluster. Update
composer placeholder/hint across 17 locales to advertise '@ files or
skills · / for commands'.
- Docs: extend skills/AGENTS.md with the curated catalogue rules
(idempotency, category vocabulary, no upstream vendoring).
Co-authored-by: Cursor <cursoragent@cursor.com>
* test(skills): teach localized-content + system-prompt tests about the skills/design-templates split
mrcfps blocking review on PR #955: the skills/design-templates split
(
|
||
|
|
b03a504da6 | release: Open Design 0.6.0 (#1080) | ||
|
|
2bb029cb58 |
release: Open Design 0.5.0 (#820)
0.5.0 已从
|
||
|
|
ae4a08773a |
chore(release): prepare 0.4.1 (#659)
- bump remaining monorepo package.json files to 0.4.1 after apps/packaged was already bumped in #637 - add CHANGELOG.md [0.4.1] - 2026-05-06 entry covering the startup hotfix and 19 merged PRs since 0.4.0: - Added: manual edit mode (#620), Cmd/Ctrl+P quick file switcher (#556), resizable chat panel (#563), PI status/cancel updates (#618), accessibility and RTL/Bidi craft modules (#587, #595), i18n structure checks (#608) - Changed: first-PR README links now surface help-wanted issues (#605) - Fixed: packaged contracts runtime exports (#577), packaged runtime beta gating (#637), ACP/MCP/agent fixes (#604, #612, #627), conversation error recovery (#623), native mac quit (#637) - Documentation/Internal: OD_DATA_DIR migration docs (#570), Simplified Chinese QUICKSTART (#578), zh-TW/ko README syncs (#586, #619), generated metrics (#592) Release workflow validation runs after merge via release-stable. |
||
|
|
8762f06297 | Add i18n structure checks (#608) | ||
|
|
963bbf2500 | release: Open Design 0.4.0 (#454) |