fixing/merge-conflict - #1
Open
Pavitra-programmers wants to merge 3960 commits into
Open
Conversation
* fix(app): keep sign-in URL visible * test(evals): prove visible sign-in URL
) * feat(desktop): debug-only nuke & fresh start with full state wipe * test(evals): fraimz flow for debug nuke & fresh start on Windows * test(evals): split Windows nuke proof commands below cmd limits * test(evals): use encoded PowerShell for Windows nuke witnesses * test(evals): stabilize renderer auth fixture after reload * fix(desktop): fail closed when bootstrap cannot be sanitized during nuke * test(evals): assert clean default preferences after nuke * test(evals): tolerate bounded Daytona exec jitter in Windows nuke proof * test(evals): flatten Windows PowerShell nuke probes * test(evals): distinguish wiped state from clean runtime regeneration * fix(desktop): retain pending nuke cleanup until locked paths are gone * fix(desktop): finish locked nuke cleanup out of process before relaunch * fix(desktop): wait for Chromium debug port release before nuke relaunch * fix(desktop): reprobe debug port after out-of-process nuke relaunch * test(evals): parse JSON before trailing PowerShell CLIXML * test(evals): use out-of-band Windows boot for locked nuke retry * test(evals): wait for cold Windows lock helper startup
Keep model and thinking controls available during ordinary assistant generation while disabling them for steered runs.
* fix(app): hide build identifier from sidebar * test(evals): remove obsolete sidebar identifier flow
* fix(app): keep session spinner clear of title * test(evals): prove session spinner spacing
* feat(desktop): make bootstrap preservation optional * test(evals): prove bootstrap nuke toggle
* feat(marketplaces): safely delete custom marketplaces * test(evals): prove custom marketplace deletion * feat(marketplaces): move management into actions menu * fix(marketplaces): hide built-in management actions * fix(marketplaces): hard-delete custom marketplace records
…anced diagnostics (#2975) * feat(mcp): add cloud MCP doctor — probe trace, engine refresh, advanced diagnostics The openwork-cloud meta-MCP fails opaquely today: OpenCode stores only Error.message for a failed remote connect (a TLS/proxy failure collapses to the literal "fetch failed"), never retries on its own, and the desktop card reduces everything to "Couldn't apply Cloud access to this workspace". Server: - Direct endpoint probe now records a per-step trace (initialize, initialized notice, tools/list) with HTTP status, latency, endpoint server info, and — on transport errors — the full cause chain (code/errno/syscall) that the engine discards. - New POST /workspace/:id/mcp/openwork-cloud/engine-refresh: disconnects the engine's MCP client, re-registers from the persisted desired config (an unconditional fresh connect on the engine side), and returns ordered refresh steps plus probed health. - Health now carries engineInspection — the engine's full MCP server map with per-server states and raw error strings — so support can tell "everything failed" (host network path) from "only openwork-cloud failed" (endpoint or token) from "entry lost after an engine restart". - Health gains durationMs; reconcilePersistedOpenworkCloudMcp accepts providerModel. App: - Test now requests probe=1, verifying the Cloud endpoint directly from the OpenWork server instead of only reading the engine's cached state; the Advanced settings page refresh does the same. - The Agent access card gains a collapsed-by-default Advanced diagnostics section: failure code/stage/retryability, the raw engine error, delivery revisions, probe step trace, engine MCP server map, token expiry, versions, a Refresh engine connection action, and a redacted copyable support bundle. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(mcp): keep behavior outside diagnostics unchanged under richer errors Two hardening guards from a behavior-impact audit: - inferFailedStatus: certificate/TLS transport errors (which can contain "expired", "auth"(ority), or "revoked" wording — especially once engines preserve error cause chains) are never classified as token or session problems; they stay generic connection failures. Prevents richer engine error strings from changing the repair verdict. - engine-refresh route: an empty body stays allowed, but malformed JSON is now a hard 400 instead of being silently treated as empty. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* chore(app): remove dead primitives * fix(evals): wait for persisted assistant response * fix(evals): assert current extensions labels * fix(evals): use canonical reopen proof
* feat(diagnostics): add Connect debug proxy * chore(diagnostics): fix publication formatting * fix(diagnostics): preserve proxy during desktop auth * fix(diagnostics): proxy Den browser auth routes
* test(den): cover MCP OAuth refresh lifecycle * fix(den): tolerate concurrent MCP token refresh (#2963)
… fork, mismatch guard, verified handoff) (#2973) * feat(installer): point paste screen back to the install page + expired-link message * feat(den-api): add desktop handoff status * feat(den-web): confirm desktop handoff connection * feat(desktop): read bootstrap synchronously on launch * feat(app): add first-run organization join option * feat(app): guard managed server sign-in links * feat(evals): first-connection voiceover + scaffold * fix(den-api): stamp configured-dir installer zips + candidate filenames; den-web: mint install links on active origen * feat(evals): first-connection flow implementation + den-stack hardening * fix(evals): handle email-first den sign-in * fix(evals): avoid empty den auth submit * fix(evals): capture bare installer fallback state * fix(evals): expire throwaway install link * fix(evals): assert current desktop signin server * fix(evals): reset installer dry-run bootstrap * fix(evals): wait for desktop server connection label * fix(evals): reset first-connection onboarding state * fix(evals): read visible desktop signin link * fix(evals): reload desktop welcome reset * fix(evals): clean invitee browser tabs * fix(evals): keep invitee browser alive * fix(den-api): stamp generic Windows installer downloads * test(evals): add first-connection Windows evidence * test(evals): note server sandbox id
* refactor(app): consolidate markdown rendering * fix(evals): validate visible highlight evidence * fix(evals): reset markdown search state
…rebuild (matches @openwork/types) (#2983)
* feat(evals): typed runner core + automation/demo mode split - pnpm evals = automation mode: no voiceover/narration policy anywhere - pnpm fraimz = demo mode: unchanged behavior (drift check, narrated frames) - runner converted to TypeScript on Node 24 native type-stripping (no build step, no new runtime deps); run.mjs stays as a thin bootstrap - typed flow contract: defineFlow + FlowContext (evals/runner/flow.ts); new flows are *.flow.ts, legacy *.flow.mjs still load via compat shims - scaffold emits typed .flow.ts stubs; plain stub without a script in automation mode, approved script still required in demo mode - OPENWORK_EVAL_VOICEOVERS_DIR override for fixture isolation - tsc gate (pnpm evals:typecheck) + runner unit tests (pnpm evals:test) - nightly workflow pinned to pnpm fraimz --all to keep drift coverage * feat(evals): typed-automation-dx internal demo flow Narrated internal demo (approved script: evals/voiceovers/typed-automation-dx.md) proving the DX end to end: mode split wiring, drift decoupling, scriptless typed scaffold, tsc contract gate, legacy compatibility, and demo-path default. * fix(helm): point den-api entrypoint guard at den-stack.ts The chart test cross-references the eval den-stack to keep the den-api entrypoint consistent; den-stack.mjs became den-stack.ts in this branch.
* refactor(app): centralize workspace server clients * fix(evals): parse workspace session route safely
* feat(den-web): offer OpenWork Cloud from install page * feat(desktop): add OpenWork Cloud installer distribution * fix(install): enforce desktop distribution doors * fix(den-web): keep Cloud install handoff simple * fix(den-web): make Cloud download the primary action
…3184) * feat(settings): add Extensions inventory primitives and i18n Add SettingsGroupHeader, SettingsFactRow, ExtensionRequirementList, resolveExtensionInventoryGroup, and updated Extensions copy. Co-authored-by: Cursor <cursoragent@cursor.com> * refactor(settings): retire Connect tab into Extensions and Debug Redirect /settings/connect to Extensions, move Agent access into Debug, and keep Connect row helpers for inventory grouping. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(extensions): group inventory by readiness and unify detail state Render Extensions cards under Needs sign-in / admin / Ready / Available / Disabled headers, relabel MCP as App, and collapse detail targets into one state (full /settings/extensions/:id page still TODO). Co-authored-by: Cursor <cursoragent@cursor.com> * feat(composer): nest apps under Extensions; update Connect guidance Drop the separate MCPs tools rail section and point agent knowledge at Settings > Extensions (and Debug for repair). Co-authored-by: Cursor <cursoragent@cursor.com> * chore(server): point runtime steering at Extensions inventory Co-authored-by: Cursor <cursoragent@cursor.com> * feat(extensions): open extension detail as a dedicated settings route Route `/settings/extensions/:id` to a page shell while keeping mcp/skills/plugins as section aliases, so deep links and back navigation stay shareable. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: GitHub Action <action@github.com>
* fix(desktop): isolate explicit bootstrap activation * fix(desktop): prioritize enterprise activation policy * fix(app): gate sign-in behind enterprise activation * fix(desktop): preserve branded enterprise activation links
#3184 left ManageInDenButton referencing openDesktopUrl, t, and ArrowUpRight without imports. The button is dead code today, but its i18n key exists, so keep the teammate's in-progress path rather than deleting it. The Extensions inventory initialFilter was also inferred as a bare string before being passed to mcpView. Type it as ExtensionsInventoryFilter so dev's @openwork/app typecheck stops failing for everyone.
* fix(composer): collapse pastes only on overflow * fix(composer): render pasted text normally * fix(composer): support paste chips before sessions
* fix(app): render markdown tables in the artifact editor Markdown artifacts open in the CodeMirror merged view, which was configured with the CommonMark base grammar, so GFM tables were never parsed and the live preview had no table case. A document full of tables showed up as raw pipes, divider row included. Parse with the GFM base and replace each table with the same sanitized HTML the rest of the app renders markdown with. Selecting into a table hands the markdown source back, so the document stays editable. Block decorations may not come from a view plugin, hence the separate state field. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(app): keep rendered tables reachable by click and arrow keys Clicking a rendered table put the cursor on its first line whatever row was clicked, and vertical cursor motion stepped over the whole block because a replaced range has no text positions inside it, so a keyboard user could not get into a table at all. Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
* chore: remove the openwork-orchestrator
The orchestrator was the last thing standing between OpenWork and a single
server binary. Cloud already ran without it; this removes it everywhere else
and deletes the package.
Render workers are now purely openwork-server: the build installs the
published npm package instead of the orchestrator, the start command drops
every orchestrator-only flag (--remote-access becomes --host 0.0.0.0,
--opencode-source/--opencode-bin become OPENWORK_MANAGE_OPENCODE and
OPENWORK_OPENCODE_BIN, --allow-external and --connect-host simply go), and it
resolves the extension plugins from the installed package - failing loudly if
they are absent rather than booting into the silent
extensions_plugin_missing state Cloud just hit. install-opencode.mjs reads
the pinned OpenCode version from the repo's own constants.json instead of
from the globally installed orchestrator.
The desktop stops shipping it. It was compiling, signing, notarizing and
shipping eight orchestrator binaries per release that nothing ever ran:
engineStart has always hardcoded the direct runtime, and both
startOrchestratorRuntime and startDirectRuntime were defined and never
called. The dead runtime paths, the detached-start IPC and its types, and the
sidecar packaging entries are gone; boot now calls engineStart directly
instead of a vestigial orchestratorWorkspaceActivate that only delegated to
it.
The single-container and microsandbox images run openwork-server directly,
with the plugins shipped and OPENWORK_EXTENSIONS_PLUGIN_DIR set. Their data
directory keeps its historical name on purpose - existing deployments have
volumes mounted there and renaming it would silently orphan their state. That
is a directory name only; the CLI is gone.
The release pipeline loses the sidecar job and the npm publish, and
verify-tag, review and bump-version no longer read a package.json that no
longer exists - they would have thrown on every release.
Legacy cleanup is deliberately preserved: users still have
~/.openwork/openwork-orchestrator on disk, so nuke keeps wiping it and the
tests keep asserting that.
Verified: apps/orchestrator deleted and the lockfile updated; app, server,
desktop-electron, den-api and den-web typechecks clean; 53 desktop electron
tests, 20 den-api cloud tests, 20 server db/env tests and the stats tests
pass; i18n audit passes across all locales; release review and verify-tag run
clean without the folder; every changed YAML parses. The server suite is
1083 pass / 7 fail, byte-identical to the pre-existing baseline on clean dev
(reload watcher/event timing plus one suite-order plugin test). The landing
prebuild parity check also fails identically on clean dev - unrelated.
* test(evals): make the cloud e2e sign-in frame state-independent
Frame 2 asserted the org-chooser screen, which only appears when a workspace
or server is already configured in the browser profile. It passed on the
dirty profiles I had been reusing and failed on a clean one - the app
legitimately lands on the first-run welcome screen instead.
It now proves what the frame actually claims: Den accepts the signed-in
admin session (node-side /v1/me, asserting the email matches), the browser
carries it, and the forced sign-in gate is no longer blocking. The wait is a
positive one for any settled post-gate surface, because a negative wait
passes on the empty DOM right after reload and the capture then lands on the
"checking" flash where app-root re-renders the gate.
Two runner behaviors worth recording: ctx.eval does not await promises, so an
async IIFE serializes to {} - probes belong node-side; and the screenshot
validator sees a later moment than the assertions, so transient states must
be waited out, not asserted around.
* fix(scripts): let the Daytona snapshot build run on arm64
The snapshot image is always linux/amd64 because that is what Daytona runs,
but the Dockerfile's runtime asserts execute the installed binaries. On an
arm64 machine those x86_64 binaries run under emulation and die with
"Illegal instruction (core dumped)", so the script could never build a
snapshot on Apple Silicon - it failed at the final assert stage every time.
Default RUNTIME_ASSERTS to 0 when the host is not x86_64, which is exactly
the cross-build path the Dockerfile already documents as "binaries must be
verified on target hardware". x86_64 hosts and CI keep asserting as before,
and the chosen value is echoed so a cross-build is obvious in the log.
* feat(extensions): name apps, connections, and MCPs consistently Extensions rows now say what they are: apps run on this device, connections are accounts, MCP servers are servers configured here. Each is filterable, and the browse catalog of things you never installed is gone -- the page lists what you have plus built-ins you can turn on. Manual MCP setup moved into Advanced settings. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(extensions): drop Google Workspace as a local extension Google Workspace now reaches OpenWork through an OpenWork Cloud org connection, so the desktop no longer ships it as a built-in extension with its own local OAuth panel. Every remaining built-in runs on this device, which lets the taxonomy drop the manifest surface flag and the runtime connection registry that only Google Workspace used. --------- Co-authored-by: Cursor <cursoragent@cursor.com>
…iled failure attribution (#3199) Extend the Agent Context cloud catalog probe into a full independent runtime MCP verification of the managed openwork-cloud endpoint: - Name the runtime transport explicitly (runtimeDiagnosticFetch + runtimeDiagnosticTransportInfo in server-fetch.ts) so reports state whether Node/undici (Electron main or standalone Node), Bun's fetch, or a test seam performed the probe, and harden the bare-fetch guard so reference fallbacks such as `?? fetch` can no longer bypass it. - Decouple probe eligibility from cached OpenCode registration state and from agent tool policy; both remain reported dimensions and become comparison inputs for a new differential verdict instead of gates. - Run the complete bounded MCP handshake: initialize (with protocol version validation), notifications/initialized, tools/list, and a bounded best-effort DELETE session cleanup that never converts a successful availability check into a failure. No tool is ever called. - Attribute failures precisely: closed stage enum (dns/connect/tls/ proxy/initialize_*/initialized_notification/tools_list_*/ catalog_validation/session_cleanup), closed sanitized network-cause codes, split HTTP classes (401/403/404/429/502-504/redirects), split protocol classes (utf8/json/envelope/request-id/protocol-version/ session-header/catalog/pagination), and deterministic retryability derived only from closed code sets. - Accept forward-compatible catalogs: extra provider tools no longer fail validation, but only the allowlisted expected tool IDs and aggregate counts are exported; both required tools must be present. - Add a cloud-endpoint-differential check distinguishing endpoint availability from engine availability (runtime_and_engine_connected, runtime_connected_engine_failed, runtime_failed_engine_connected, runtime_and_engine_failed, runtime_probe_not_performed, engine_evidence_stale_or_unavailable) with engine evidence source and age surfaced. - Keep the trust boundary: only built-in Cloud origins, exact administrator-configured origins, and loopback may receive the credentialed probe; untrusted_endpoint is reported as probe-not- performed trust configuration, never as a network or MCP failure. Boolean-only proxy/extra-CA posture and a strictly validated x-request-id reference are the only environment-derived exports. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…tance (#3191) First slice of ui.openworklabs.com. den-gateway serves the OpenWork web build and proxies each signed-in user to their own Cloud instance, injecting that instance's credentials server-side. The browser never receives an instance token or a preview URL, and never learns which compute vendor is behind it. The security boundary is the point: the gateway holds no Daytona key, never imports the SDK, and has no database access. den-api remains the only thing that talks to Daytona. The gateway also cannot assert identity on its own - it acts strictly on behalf of the caller's Den session, so den-api's per-process internal-principal secret stays untouched. den-api gains GET /v1/cloud/gateway/resolve: the caller's own session plus a shared gateway secret (timing-safe, and the route 404s when the secret env is unset, so it does not exist on deployments without a gateway). It returns the instance URL and collaborator token only when ready, never the host token, and reuses the existing per-user state machine rather than forking it. Routing is the subtle part. Every allowlisted entry matches as a namespace, because /files/sessions/*, /workspaces/local, /workspaces/:id/activate, /env/keys and /approvals/:id would otherwise fall through and answer an API caller with HTML. And /workspace/ is genuinely ambiguous - openwork-server owns API routes there while the BrowserRouter SPA owns reloadable session/settings deep links - so document navigations serve index.html while everything else proxies. /opencode/ and /w/ are always API, since openwork-server claims all of /w/. Streaming correctness is deliberate: the SPA holds two permanently-open SSE streams, so bodies are piped rather than buffered, content-encoding and transfer-encoding are stripped (undici already decoded), no idle timeout is imposed, and upstream caching passes through. Static serving mirrors openwork-server: SPA history fallback, immutable /assets caching, and a hard 404 for a missing hashed asset so a stale index surfaces as a 404 instead of HTML parsed as JavaScript. Gateway health lives at /__gw/health because /health belongs to the instance. Lands the approved voice-over and scaffolded flow for the den-gateway demo. Slice 1 only: apps/app is not wired to it yet and no deployment config is included. Verified: den-gateway builds, 10 gateway tests pass (static, SPA fallback, asset 404, traversal, injection, resolve cache, non-ready, SSE non-buffering, gzip, and every routing case above); 24 den-api cloud tests pass including the new resolve gating.
…ine-evidence staleness (#3200) * fix(diagnostics): probe activated on-prem Den origins and correct engine-evidence staleness Follow-up to #3199, from a real enterprise diagnostics report where the runtime probe could not run at all. Trust the activated enterprise control plane. An on-prem deployment's managed openwork-cloud entry points at the customer's own Den origin, so the probe reported untrusted_endpoint and sent nothing — leaving exactly the deployments that most need differential diagnosis with no evidence beyond OpenCode's opaque "failed". The desktop writes enterpriseActivation only after a signed activation claim verifies, so that record is administrator-provisioned configuration rather than a renderer- or request-supplied URL. The server now reads it (bounded, read-only, local workspaces only) and admits its exact origin to the diagnostics allowlist. Arbitrary URLs, non-https origins, and credential-, query-, or fragment-bearing values are still rejected, and a missing or malformed record fails closed. Report trust provenance instead of the origin. trustSource (builtin-cloud | loopback | administrator-env | enterprise-activation | untrusted | not-evaluated) and enterpriseActivationPresent let an administrator tell "this install is not activated" apart from "it is activated, but against a different origin than the configured Cloud MCP" — a real misconfiguration that previously looked identical — without the report ever carrying a hostname. Correct the differential staleness rule. Treating any engine record older than 60s as stale made every healthy steady-state run report engine_evidence_stale_or_unavailable, because a connected registration is the engine's standing state and ages naturally between syncs. Only a failure record the reachable engine could already have refreshed is downgraded, mirroring mcp_registration_stale_failure; an aged failure on an unreachable engine keeps implicating the engine. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * test(diagnostics): assert the probe only ever reaches the configured Den endpoint An on-prem operator's probe must reach their own Den deployment, never OpenWork-hosted Cloud. The built-in origins are a membership allowlist consulted with .has() and are never a destination or fallback, but that invariant was only enforced by inspection. Pin every request URL of the handshake and the session cleanup to the exact configured endpoint, and assert no OpenWork-hosted origin is contacted, at both the probe and analyzer levels. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…able image (#3202) * feat(den-gateway): run the app behind the gateway on one origin Wires apps/app to den-gateway so browser traffic is single-origin and the browser holds no instance credential. - The gateway proxies /api/den/* to den-api, forwarding the caller's Den bearer unchanged (Den is the intended audience) and never attaching the gateway key, which is only for the resolve call. Cookies are not forwarded; the SPA is bearer-authenticated. Same streaming rules as the instance proxy. - The gateway injects a token-free marker into index.html so the app can tell it is behind a gateway. - In gateway mode the app resolves the OpenWork server base and the Den base from window.location.origin, sends its Den session token as the bearer, and ignores window.__OPENWORK_BOOTSTRAP__ entirely, so no instance token is ever written to storage. Because both the app and Den are same-origin behind the gateway, this is what makes the three CORS patches from this week unnecessary rather than load-bearing. Desktop and the existing direct-instance path are untouched when the gateway marker is absent - asserted by tests covering bootstrap-token hydration, stored settings precedence, and desktop server info. Verified: gateway builds; 13 gateway tests and 6 app gateway-runtime tests pass; build:web succeeds. apps/app tsc has 5 pre-existing errors on dev (agent-access-card.tsx, extensions-view.tsx) confirmed against a clean base; none added here. * fix(den-gateway): allow gateway sign-in returns * fix(den-gateway): suppress instance web token * feat(den-gateway): package gateway image and publish in CI Bake the OpenWork web build into the gateway image so the app and Den share one origin, and register the image in the EE publish matrix. The gateway's own liveness is /__gw/health because /health proxies to the user instance. * fix(ci): build newly added EE images instead of skipping them The build step's condition was an allowlist of image names, so a new matrix entry silently skipped the build and then failed the smoke step with a confusing registry 'denied' error. State it as an exclusion instead.
…nstaller app (#3203) * fix(desktop): load system CAs from OS trust stores for engine TLS trust resolveSystemCaEnv had one source, tls.getCACertificates("system"), which returns 0 certificates on macOS and misses intermediates outside the ROOT store on Windows. Behind a corporate CA the Chromium surfaces worked while OpenCode (Bun) failed every TLS connection to the org endpoint with 'unable to verify the first certificate'. - port the additive loader to apps/desktop/electron/system-ca.mjs: Windows LocalMachine/CurrentUser Root+CA stores via PowerShell, macOS admin keychains via security find-certificate, merged and deduped into system-ca-bundle.pem for NODE_EXTRA_CA_CERTS - extend the Electron main process default CA set with the same additions (best-effort tls.setDefaultCACertificates) so the embedded OpenWork server's own probes trust the corporate CA; env mutation after boot never reached it - operator-set NODE_EXTRA_CA_CERTS keeps its skip-and-win semantics * chore: remove the obsolete standalone installer app The generic installer (apps/installer) is replaced by the release pipeline shipping desktop assets directly. Remove the app, its build and release workflows, eval flows, version bumping, outbound-access scan entry, and the OpenWork-Installer-* asset plumbing in den-api install links, den-web install screens, and the landing release-asset filter. Configured install-link artifacts now resolve by the standard versioned desktop asset filename. packages/install-config and packages/paths stay (install links are a Den feature). * chore: drop unrelated whitespace and grep-dodging edits from the merge
…ll dead-end (#3204) Stable/enterprise users hit "Couldn't check for updates" with the raw reason update-not-downloaded when clicking Install & restart: the main process cleared its in-memory updateDownloaded flag on ANY updater error event and on transient failed checks, while the renderer's "Ready to install" state never learned about the reset. - main: only a successful check proving no update (or a real download failure) invalidates a staged download; transient errors no longer do - renderer: an install attempt that hits the stale flag now re-runs the policy-aware manual check and lands back on a working download flow instead of dead-ending on a raw internal reason - view: action-specific error headlines (install/download vs check) - tests: fake-updater lifecycle regression tests via loadAutoUpdater seam - evals: update-install-self-heal fraimz flow + voiceover
… transport evidence (#3201) Self-hosted Den deployments behind corporate TLS failed openwork-cloud MCP registration for three weeks with zero captured cause: the engine's error string was discarded at parse time, the credentialed catalog probe fails closed for self-hosted origins, and mcps[] hid the real endpoint. - persist OpenCode's registration error (sanitized, bounded) through the registration record into engine-mcp-sync failedRegistrations, with a classified transportCause (tls_incomplete_chain, tls_untrusted_ca, ...) - scrub URL/path segments to [url]/[path] placeholders instead of whole-string redaction so endpoint-bearing TLS errors survive sanitization - new credential-free cloud-endpoint-transport check: bare TLS handshake captures the exact verify error code, served chain length/subjects, and local trust evidence (system CA count, NODE_EXTRA_CA_CERTS state) - report real origin + path for managed openwork-cloud MCP entries - keep the credentialed-probe trust gating and report-safety claims intact
…3206) * fix(diagnostics): omit SNI servername for IP-literal cloud endpoints tls.connect with servername set to an IP literal throws ERR_INVALID_ARG_VALUE on Node (SNI forbids IP addresses), so the transport probe misreported configuration errors as verify failures for IP endpoints and broke three tests on CI runtimes that enforce the rule. Strip IPv6 brackets for the host and set servername only for DNS names. * fix(desktop): default the updater loader so the IPC contract typecheck passes registerUpdaterIpc gained a required loadAutoUpdater seam in #3204 but main.mjs and the test fixtures never passed it, breaking the Electron typecheck on dev. Declare the electron-updater import as the parameter default, which both fixes the inferred contract and simplifies ensureAutoUpdater.
…URL without an org (#3207) * fix(app): scope gateway Den API origin * fix(den-api): approve gateway handoff without active org
…ing sign-in again (#3209) * fix(app): reflect gateway session after web handoff * fix(app): avoid blank welcome when den unavailable
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Why
Issue
Scope
Out of scope
Testing
Ran
...Result
CI status
Manual verification
Evidence
N/A (docs-only)Risk
Rollback