fixing/merge-conflict - #1
Open
Pavitra-programmers wants to merge 3978 commits into
Open
Conversation
* 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
…mping, zero-env serving (#2990) * feat(den-web): install page copy for the paste-gated installer door * ci(release): publish paste-gated installer assets with every app release * feat(installer): paste-gated installer, remove artifact stamping; mac DMG packaging * fix(app): welcome fork as option cards, restore Get started primary * feat(den-api): install door always serves the installer (302 by default, mirror optional); remove stamping * test(evals): first-connection on the paste-gated two-door model * docs(evals): two-door-install voiceover
…nshot primitive (#2988) * feat(evals): pretty screenshot primitive (mesh-gradient frame, cross-OS) pretty: true on the screenshot primitive composites the raw capture onto the checked-in paper mesh-gradient brand background (rendered from @paper-design/shaders@0.0.72 with the packages/ui brand palette) with padding, rounded corners, and a soft drop shadow. Compositing runs inside the app's own Chromium via CDP (detached canvas + roundRect + toDataURL): no OS tools, no native deps, no platform branches — identical output on Linux, macOS, and Windows. Pixel-level checks (gradient corners, rounded clip, shadow darkening, center integrity) are recorded as frame validations; duplicate detection still hashes the raw capture. * fix(evals): pretty-screenshot flow matches workspace-scoped settings routes * fix(evals): restore session route after pretty demo; harden nested run-id parsing - pretty-screenshot flow leaves the app on the session surface it found (flows-are-idempotent convention; keeps core-flow's precondition healthy in multi-flow runs) - voiceover-first-dx anchors the nested red-run id on the full run-id shape so a random mkdtemp suffix in the Report path can't first-match
* feat(server): create sessions without UI control * test(evals): cover plain-language session creation * fix(app): surface background-created sessions * fix(server): remove session creation batch cap
…p (fixes Windows test run) (#3002)
* fix(den): serialize default marketplace seeding * fix(den): preserve safe database diagnostics * test(den): scope marketplace seed cleanup
…ump PR, tag, Release App, installer assets, retag caveat) (#3005)
* feat(cloud): add organization super-admin role * test(server): remove concurrent session ordering assumption
…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
Add opt-in desktop integration for packaged Linux AppImages so browser sign-in callbacks have a working openwork:// handler. - Install a per-user XDG desktop entry, hicolor icons, and register x-scheme-handler/openwork. - Detect moved AppImages and offer repair. - Defer to externally managed AppImages (AppImageLauncher, Gear Lever) without duplicating or overwriting their launchers. - Add Preferences controls, unit coverage, packaging assertions, and a fraimz desktop-integration flow. Closes #3216
…e worker forever (#3219) * fix(den-api): adopt existing Daytona sandboxes * test(den-api): cover Daytona sandbox adoption
Linux artifacts carry the version in their filename, so electron-updater installs each release at a new path. The desktop entry then pointed at the old file, openwork:// callbacks broke, and the user was asked to repair the integration after every release. Treat drift in an entry OpenWork already owns as maintenance rather than a new decision: repair it silently on the next start. The first-run opt-in prompt is unchanged, externally managed AppImages are still never touched, and a failed silent repair logs instead of showing a dialog every launch. Follow-up to #3217.
#3221) * perf(extensions): prefetch the organization inventory so Ready to use paints immediately The Connect capability fan-out (marketplaces, every resolved marketplace, every resolved plugin) and the org MCP connection list were fetched after Settings mounted, and Settings remounts every time the extensions panel opens, so the Ready to use group waited on Den every single time. The composer and the new-task composer each kept their own component-scoped copy of the same fan-out. Move both behind one module-scoped cache, warm it at app start and on Den session changes, and let views paint the last known answer on their first frame while revalidating behind it. While the first fetch is genuinely in flight the inventory now shows skeletons instead of claiming there are no extensions. * feat(extensions): add a list view next to the card view Tiles are good for browsing a handful of extensions and bad for scanning a long organization inventory. The inventory now switches between cards and dense rows from a toggle next to the filters, and remembers the choice. Both layouts are the same ExtensionCard, split into shared icon, badge, and action pieces so readiness never renders two different ways. * fix(extensions): show organization connections that still need your sign-in Settings only passed org connections whose installState was "installed", so a connection the organization provisioned for a member stayed invisible until that member had already connected it — which they could not do, because the row was not there. For most members the Connections filter was simply empty. The readiness grouping already knew what to do with these (resolveConnectionRowGroup returns needs_signin), it just never saw them. The empty Connections state now also says where connections come from instead of suggesting the user add an MCP server.
New members landed on a row of Disabled / 0 cards that only repeated the real sections below. Remove the overview so Your workspace goes straight into providers, models, marketplaces, and plugins. Co-authored-by: Cursor <cursoragent@cursor.com>
…ility (#3225) * feat(den-api): add admin org capability MCP tool * fix(den-api): pin admin MCP org capability test env
* feat: Resume Den Skill CRUD and prove the complete body Open-Work-Snacks-Run: b4bbf743-6374-4e50-a7d0-0d44fd2306c3:9a848f4f2e93b3aa296e564243b7edbd6946df5aa30d99ae25c96a8700d17a14 * feat: Move Skill CRUD into the Plugin management flow Open-Work-Snacks-Run: 5906d5b7-4948-4492-ad8e-a3b4ca721cd2:aba6e8928d87493f302a12e52379c7f5e51f1518040fcae3ef247ce4fa574a02 * feat(den): manage plugin metadata and lifecycle * fix(den): hide deleted skills from plugins --------- Co-authored-by: open-work-snacks <open-work-snacks@users.noreply.github.com>
* fix(den): honor grants for admin desktop skills * test(evals): prove admin desktop skill grants * test(evals): prove admin skill search grants * fix(connect): scope desktop capabilities to grants * test(evals): select workspace for MCP proof * test(evals): reveal inactive MCP entries * test(evals): prove assigned MCP connection context * test(connect): update capability inventory fixtures
…nto the pinned snapshot (#3228) * feat(den-api): checkpoint Daytona sandbox state * feat(den-api): recycle stale Daytona sandboxes * fix(den-api): avoid checkpoint probes during resolve
…on exists (#3226) * fix(app): allow attachments in the new-task composer before the session exists Feedback: the attachment button on the New Task page was disabled until the first message created the session, so tasks that need a file up front hit a circular dependency. The hero composer now collects attachments in memory, and running the task seeds them (with the draft) into the created session's composer state, where the normal auto-send path uploads them into the worker workspace inbox and sends them with the first message. * test(evals): prove new-task composer attachments end-to-end Frames: attach a CSV on the empty New Task screen (no session), run the task, and witness the first message carrying the attachment plus the exact bytes landing in the worker workspace inbox (sha256-verified via the Daytona sandbox). * test(evals): prove new-task attachments when no workspace exists yet The New Task composer also renders with zero workspaces (chat-first onboarding). Frames: attach a CSV with an empty workspace list, press Run task once, and witness the workspace being created, the first message carrying the attachment, and the exact bytes (sha256) landing in that new workspace's inbox.
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