mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
hyperframes-html-in-canvas
10
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2bb029cb58 |
release: Open Design 0.5.0 (#820)
0.5.0 已从
|
||
|
|
2455c70d51 |
fix(daemon, packaged): unbreak GUI-launched agent detection on minimal PATHs (#442) (#614)
* fix(daemon, packaged): unbreak GUI-launched agent detection on minimal PATHs (#442) GUI-launched daemons (Finder/Dock on macOS, .desktop on Linux) inherit a stripped PATH from launchd / the desktop session and don't read the user's interactive shell rc files, so any CLI installed via `npm i -g` under a sudo-free prefix like ~/.npm-global was silently undetected. Two layers maintained their own copies of the user-toolchain bin list (`apps/daemon/src/agents.ts:userToolchainDirs` for the resolver, `apps/packaged/src/sidecars.ts:resolvePackagedPathEnv` for the packaged sidecar PATH builder) and had already drifted on `~/.asdf/shims` and `~/Library/pnpm`. Adding ~/.npm-global to one side would have preserved the same anti-pattern. Extracts `wellKnownUserToolchainBins` into @open-design/platform as the single source of truth, has both layers consume it, and extends the list to cover ~/.npm-global/bin, ~/.npm-packages/bin, plus $NPM_CONFIG_PREFIX/bin / $npm_config_prefix/bin for users with a non-standard prefix. New vitest coverage in the platform package and a regression test in apps/daemon/tests/agents.test.ts modelled on the existing mise case. Verified end-to-end: under PATH=/usr/bin:/bin:/usr/sbin:/sbin (the launchd default a `.app` actually inherits), `resolveAgentExecutable` now returns ~/.npm-global/bin/gemini instead of null. * fix(daemon): isolate OD_AGENT_HOME resolution from $NPM_CONFIG_PREFIX leakage Address review feedback on PR #614: - mrcfps spotted that the daemon wrapper called wellKnownUserToolchainBins without passing `env`, so the helper read its default process.env. A developer or CI runner with NPM_CONFIG_PREFIX / npm_config_prefix exported would inject that real <prefix>/bin into resolveOnPath() even while the OD_AGENT_HOME hook pointed home at a temp fixture, making agent-detection tests environment-dependent. Reproduced locally: with OD_AGENT_HOME=<tmp> + NPM_CONFIG_PREFIX=/Users/me/.npm-global, resolveAgentExecutable({ bin: 'codex' }) returned the real machine's binary instead of null. Wrapper now passes `env: {}` whenever homeOverride is set, alongside the existing includeSystemBins gate. - lefarcen suggested also handling whitespace-only NPM_CONFIG_PREFIX values (e.g. NPM_CONFIG_PREFIX=" ") so the helper does not emit a bogus "<whitespace>/bin" entry. Added a .trim() check before appending. - lefarcen also suggested a comment pointer from the daemon wrapper to the platform helper so readers don't have to grep. Added the reference inline. Coverage: - packages/platform/tests/index.test.ts: new whitespace-prefix case. - apps/daemon/tests/agents.test.ts: new env-isolation regression asserting that OD_AGENT_HOME + NPM_CONFIG_PREFIX cannot leak the real prefix bin into the sandbox. * test(daemon): preserve $NPM_CONFIG_PREFIX across the env-isolation case (#614) Address mrcfps's second-round review on PR #614: the env-isolation regression sets `process.env.NPM_CONFIG_PREFIX = realPrefix` in its body and then unconditionally `delete`s it in `finally`. On a developer machine or CI runner that already exported `NPM_CONFIG_PREFIX`, that mutates the worker-wide env for every later test, making downstream env-sensitive assertions order-dependent. Move the save/restore into the file's existing afterEach hook (mirroring the OD_AGENT_HOME / OD_DAEMON_URL / OD_TOOL_TOKEN pattern) and drop the in-test `delete`. Same coverage, no worker-state mutation. * fix(platform): prioritise $NPM_CONFIG_PREFIX over the conventional npm guesses (#614) Address mrcfps's third-round review on PR #614: when the user has explicitly configured a prefix via $NPM_CONFIG_PREFIX (or $npm_config_prefix), that's where `npm i -g` puts the *current* binaries. The conventional guesses ~/.npm-global / ~/.npm-packages often hold *stale* installs from an older prefix the user has since rewritten — searching the env-driven prefix first matches npm's own resolution order (env > .npmrc > default) and gives "explicit beats convention" semantics. Move the env-driven push above the conventional `dirs.push(.npm-global, .npm-packages)`. Add a vitest case in the platform package that asserts $NPM_CONFIG_PREFIX/bin's index in the result is strictly less than ~/.npm-global/bin's and ~/.npm-packages/bin's. `resolveOnPath()` and the packaged PATH builder both preserve insertion order, so first hit wins and the new ordering propagates to both layers. * fix(platform): lift $NPM_CONFIG_PREFIX above every conventional bin (#614) Address mrcfps's fourth-round review on PR #614: the previous fix only moved $NPM_CONFIG_PREFIX/bin ahead of ~/.npm-global / ~/.npm-packages, but ~/.local/bin still appeared earlier in the array. Under a minimal GUI-launch PATH a stale agent in ~/.local/bin (also a shared dumping ground for pip --user / cargo install / hand-built binaries) could outrank the user's *current* explicit npm prefix. Move the env-driven push to the head of `dirs` so the explicit prefix wins over every conventional location below — ~/.local/bin included. Matches npm's own resolution order (env > .npmrc > default) across the whole list, not just the npm-prefix block. Tightened the existing order test to assert `explicitIdx === 0` and that ~/.local/bin's index is strictly greater than the explicit prefix's index, so a future drift would fail loudly. |
||
|
|
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. |
||
|
|
963bbf2500 | release: Open Design 0.4.0 (#454) | ||
|
|
bbdd4e84b5 |
chore: enforce test directory conventions (#496)
* chore: enforce test directory conventions Move package, app, and tool tests out of src and add guard enforcement so source directories stay source-only. * ci: use guard and package-scoped tests Run the new repository guard in CI and keep test execution aligned with package-scoped commands after removing root aliases. * ci: align stable release guard check Use the new repository guard in stable release verification after replacing the residual-JS-only script. * chore: tighten test layout enforcement Enforce sibling tests directories, typecheck moved test suites with dedicated configs, and refresh remaining guidance that pointed at src-based tests. * chore: clarify no-emit test tsconfigs Explicitly disable declaration-only emit in test tsconfigs so review tooling sees they are no-emit typecheck configs. |
||
|
|
da2b007a43 |
feat(daemon): add DeepSeek TUI as a code agent adapter (#439)
* feat(daemon): add DeepSeek TUI as a code agent adapter
Register `deepseek` (with `deepseek-tui` cargo-only fallback) in
AGENT_DEFS via `deepseek exec --auto [--model X] <prompt>` and plain-text
streaming. Ships `deepseek-v4-pro` / `deepseek-v4-flash` as fallback
model hints; users can paste any other id (incl. NIM / Fireworks /
SGLang routes) via the custom-model input.
Web UI gets a DeepSeek-blue gradient icon, label/alias mapping, and
docs/agent-adapters.md §5.9 documents the auth state, prompt-as-argv
Windows size limit, and the upstream gap that prevents stdin delivery
today (clap declares `prompt: String` as a required positional).
Adds .deepseek/ to .gitignore alongside the other per-agent runtime
data dirs so first-launch trust files don't leak into git.
* fix(daemon): drop unsupported deepseek-tui fallback bin
The `deepseek` dispatcher owns `exec` / `--auto`; `deepseek-tui` is the
runtime companion it invokes. Listing `deepseek-tui` in fallbackBins
advertised availability for a host that only had the TUI binary, but
buildArgs still emitted `<resolved> exec --auto <prompt>` — which
deepseek-tui itself doesn't accept, so the first /api/chat run would
fail. Upstream documents both binaries as required (npm and cargo paths
install them together), so the fallback didn't correspond to a supported
install. Pin the absence in the agents test and update docs §5.9 + the
adapter table to match.
Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)
* fix(daemon): pre-flight DeepSeek TUI prompts against argv byte budget
DeepSeek's exec mode requires the prompt as a positional argv arg (no
`-` stdin sentinel upstream), so a fully composed OD prompt — system
text + history + skills + design-system content + the user message —
can blow Windows' ~32 KB CreateProcess limit (or Linux MAX_ARG_STRLEN
on extreme edges) and surface as a generic spawn failure instead of
a DeepSeek-specific, user-actionable message. The adapter now declares
`maxPromptArgBytes = 30_000` (leaves ~2.7 KB argv headroom for `exec
--auto --model <id>` and Windows quoting), and the /api/chat spawn
path checks the composed prompt against that budget before calling
`spawn`. Oversized prompts fail fast with `AGENT_PROMPT_TOO_LARGE`
and guidance to reduce skills/design context or pick an adapter with
stdin support.
Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)
* test(daemon): pin DeepSeek argv-budget guard with regression tests
The previous spawn-path guard inlined the byte-budget check in the
chat handler, so the only safety net for the DeepSeek argv-only
prompt-delivery shape was a static "the field exists" assertion —
nothing actually exercised the AGENT_PROMPT_TOO_LARGE path or the
short-prompt happy path. Extract the check into a pure
`checkPromptArgvBudget(def, composed)` helper in agents.ts, call it
from /api/chat before bin resolution (so the guard is order-
independent and fires regardless of whether the adapter binary is
on PATH in CI), and add a regression test that exercises both the
oversized-prompt branch (over the conservative under-Windows-
CreateProcess budget) and the short-prompt branch, plus a UTF-8
byte-vs-codepoint case and a stdin-adapter no-op case so the guard
can't silently regress or leak onto adapters that ship the prompt
over stdin.
Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)
* fix(daemon): pre-flight DeepSeek prompts against Windows .cmd-shim quoting
The first-pass argv-byte guard only inspects the raw composed prompt, so
on Windows an npm-installed `deepseek` resolves to a `.cmd` shim and the
spawn path then wraps the call in `cmd.exe /d /s /c "<inner>"` with
every embedded `"` doubled by `quoteWindowsCommandArg`. A quote-heavy
prompt (code blocks, JSON-shaped skill seeds) under the 30,000-byte
budget can therefore still expand past CreateProcess's 32_767-char
`lpCommandLine` cap and surface as a generic spawn ENAMETOOLONG instead
of the DeepSeek-named, actionable `AGENT_PROMPT_TOO_LARGE` the budget
guard was meant to provide. Add a second pure helper
`checkWindowsCmdShimCommandLineBudget(def, resolvedBin, args)` that
mirrors the platform layer's per-arg quoting and recomputes the would-be
command line length whenever the resolved binary is a `.cmd` / `.bat`
shim, and call it from `/api/chat` after `buildArgs` / `resolveAgentBin`
so the same SSE error fires before `spawn`. Pin the new path with a
quote-heavy regression (prompt is under the byte budget but doubles
past the kernel cap) plus no-op tests for non-`.cmd` resolutions, null
bin, and stdin-only adapters so the guard can't drift back.
Generated-By: looper 0.4.0 (runner=fixer, agent=claude-code)
* fix(daemon): extend DeepSeek argv guard to direct .exe Windows installs
The cmd-shim guard added in
|
||
|
|
016c08183f | release: Open Design 0.3.0 | ||
|
|
648374d839 |
fix(platform): wrap cmd.exe shim invocations to survive /s /c quote stripping (#339)
PR #258 standardized agent spawning through `createCommandInvocation`, which on Windows wraps `.cmd` / `.bat` paths in `cmd.exe /d /s /c <line>` and quotes each argument with cmd-style doubled quotes. PR #232's follow-up fix for `shell:true` was lost in that refactor, and the new shape has its own quoting bug on argv-style spawn: 1. cmd.exe `/s /c` strips exactly one leading and one trailing `"` from the rest of the command line. 2. Node, with `windowsVerbatimArguments` unset, escapes each argv element using CommandLineToArgvW rules — so the inner `"path with space"` ends up surfacing to cmd.exe with an extra layer of `\"` escaping that cmd doesn't understand. Together these collapse `"C:\Users\Ethical Byte\...\codex.CMD" --help` into `C:\Users\Ethical Byte\...\codex.CMD --help` with no quoting preserved, and cmd.exe parses the first space as a token boundary — "`Ethical` is not recognized as an internal or external command." See issue #315 for the full repro. The fix mirrors what Node's own `child_process.spawn({ shell: true })` does internally: wrap the entire joined command line in an extra `"…"` and set `windowsVerbatimArguments: true`. The outer wrap absorbs the `/s /c` strip, leaving inner per-arg quoting intact, and the verbatim flag tells Node to pass argv through to CreateProcess unchanged. Changes: - `packages/platform/src/index.ts` - Extend `CommandInvocation` with optional `windowsVerbatimArguments`. - Extract the cmd.exe shim builder into `buildCmdShimInvocation` and apply the outer wrap + verbatim flag in both `createCommandInvocation` and `createPackageManagerInvocation`. - Forward the flag through `spawnBackgroundProcess` and `spawnLoggedProcess`. - `apps/daemon/src/server.ts` — agent spawn forwards `invocation.windowsVerbatimArguments`. This is the call site that hit #315 in the wild (Codex CLI `.CMD` shim, user dir with space). - `tools/pack/src/win.ts` — `runPnpm` and `runNpmInstall` forward the flag through `execFileAsync`. Affects the Windows packaged-build pipeline when run from a path with spaces. - `tools/dev/src/index.ts` — `runLoggedCommand` accepts and forwards the flag; `buildDesktop` propagates it from `createPackageManagerInvocation`. Affects local dev on Windows. Tests: - 9 new unit tests in `packages/platform/src/index.test.ts` stub `process.platform` so both Windows and POSIX branches run on every CI runner. Coverage: - POSIX pass-through. - Windows non-shim binary pass-through. - `.CMD` shim with spaces in the binary path (the #315 repro). - `.bat` shim parity. - Argv elements with spaces alongside the shim path. - Argv elements without whitespace stay unquoted. - `process.env.ComSpec` fallback. - `npm_execpath` short-circuit (cross-platform). - POSIX pnpm pass-through. - Windows pnpm wrapped through cmd.exe. Closes #315. |
||
|
|
62b01a6dbf | release: Open Design 0.2.0 (#297) | ||
|
|
c6d11018a0 |
Refresh desktop integration control plane (#123)
* feat(dev): add desktop tools-dev control plane * refactor(sidecar): split Open Design contracts Move Open Design-specific sidecar protocol definitions into @open-design/contracts so sidecar and platform can remain descriptor-driven primitives. * refactor(daemon): organize package sources Keep daemon app code, tests, and sidecar entrypoints in separate package directories so each layer can be built and verified independently. * chore(repo): streamline maintenance entrypoints Centralize agent guidance by directory and reduce root command chains while preserving the existing build scope. * docs: translate agent guidance to English * fix(sidecar): tolerate stale IPC sockets Remove stale Unix socket files only after confirming no listener is active, so tools-dev can restart after unclean shutdowns. |