Commit Graph
3021 Commits
Author SHA1 Message Date
bestthanaponandGitHub f9d42f4770 Add Clone Audit plugin (#5687)
* Add Clone Audit plugin

* Update open-design.json

* fix: make clone audit skill reusable

* fix: sanitize clone audit provenance path
2026-07-29 04:08:31 +00:00
7f5abbd2a2 feat(landing-page): sharpen the Codex agent page for "codex ui" intent (#6200)
The /agents/codex-design/ page ranks #1 for "codex design" but only ~6th
with a 1.3% CTR for "codex ui", a query that grew from 30 to ~90 daily
impressions this month. A live SERP check shows the intent is mostly
"build UI with Codex" (our intent), with a minority looking for the Codex
app's own interface.

- Retitle to "Codex Design: Build UI with OpenAI Codex" (title + H1).
- Lead the frontend section with the query phrase and an answer-shaped
  opening paragraph, so the section is extractable for AI answers.
- Add a disambiguation paragraph separating the Codex app's own UI from
  the UI you build with Codex, and route the former back to the main line.
- Add two FAQ entries covering both readings; they also feed the FAQPage
  schema, which already earns a text snippet on this query.

Applied across all 11 shipped locales (en, zh authored; the other nine
translated with the page's terminology preserved).

Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com>
2026-07-29 03:53:21 +00:00
b6b23b77df test(e2e): parallelize restoration group (#6169)
* test(e2e): parallelize restoration group

* test(e2e): identify conversations from persisted prompts

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* test(e2e): wait for conversation persistence

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-07-29 03:53:06 +00:00
af2a833506 fix(daemon): surface AMR OpenCode stall context (#6040)
* fix(daemon): surface AMR OpenCode stall context

* fix(daemon): accept runtime-omitted OpenCode diagnostics

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(ci): make static gate runner-independent (#6039)

---------

Co-authored-by: PerishFire <39043006+PerishCode@users.noreply.github.com>
2026-07-29 03:52:39 +00:00
PerishFireandGitHub f52fda29a8 test(e2e): remove redundant UI setup (#6161) 2026-07-28 11:19:02 +00:00
Ethan GuoandGitHub f9ccdfc4e3 fix(web): prune per-project tab-state cache on project deletion (#5761) 2026-07-28 09:56:38 +00:00
Gary CrumandGitHub cf8dc13853 docs(wsl): point daemon reachability check at /api/health (#5877)
The WSL2 setup guide verified daemon reachability by curling the root
URL, which returns 404 on a fresh source install because pnpm install
does not build apps/web, so nothing is served at /. The daemon's
unauthenticated /api/health endpoint responds regardless of the web
build, so probe that instead, and document the optional web-UI build
for users who want the browser UI at the root URL.
2026-07-28 09:51:36 +00:00
PerishFireandGitHub 91d8244fa1 test: consolidate workspace restoration coverage (#6158) 2026-07-28 09:36:15 +00:00
PerishFireandGitHub bfa7060372 test: remove redundant UI P0 variants (#6153) 2026-07-28 07:59:40 +00:00
PerishFireandGitHub 89d6d4ef21 test: remove redundant browser smoke coverage (#6148)
* test: close browser resources before runtime shutdown

* test: remove redundant browser smoke coverage
2026-07-28 06:41:47 +00:00
PerishFireandGitHub a7e205939d test: remove deterministic CI waits (#6144)
* test: remove deterministic CI waits

* test: stabilize workspace restoration reload
2026-07-28 04:46:56 +00:00
PerishFireandGitHub e0d91046dd refactor(desktop): extract deferred launch and release lifecycle, completing the updater split (#6139)
* refactor(desktop): extract deferred launch helpers into updater/deferred-launch

Mechanical move out of updater.ts: the embedded mac shell and Windows
PowerShell wait-for-pid installer-opening scripts, their writers and
spawn plumbing, and the payload after-quit launch move to
updater/deferred-launch.ts. updater.ts re-exports the three deferred
launch input/result types; orphaned imports pruned. Region-based cut
(the PS1 heredocs contain column-zero braces, so this slice moves as one
contiguous span).

* refactor(desktop): extract the release cleanup lifecycle into updater/release-lifecycle

Mechanical move out of updater.ts: the release cleanup.json descriptor
types and guards, deprecate/remove scanning with deferred-failure retry,
the mkdir-based lifecycle lock, and the .back directory sweep move to
updater/release-lifecycle.ts. The DesktopUpdater interface type stays in
updater.ts; orphaned imports pruned. This completes the split: updater.ts
is now the assembly layer plus the state machine and download/install
orchestration.
2026-07-28 03:07:07 +00:00
PerishFireandGitHub c893b60aa3 refactor(desktop): extract the launcher payload lifecycle into updater/payload (#6114)
* refactor(desktop): extract the launcher payload lifecycle into updater/payload

Mechanical move out of updater.ts: payload manifest validation, archive
extraction (ditto/7z + mac xattr scrub), prepared-release verification,
payload activation with attempt pre-arming, and the launcher-side
cleanup machinery (deferred failures, retention, cold-start retry sweep,
manual-clear state reset) move to updater/payload.ts. updater.ts
re-exports LauncherPayloadExtractInput so the public surface is
unchanged; orphaned imports are pruned. No test files change: payload
coverage is integration-style and the desktop suite holds at 269.

* test(pack): follow the mac xattr-scrub assertion to updater/payload

release-workflows.test.ts pins the updater-side mac quarantine-xattr
scrub by reading the desktop updater source; the scrub moved to
src/main/updater/payload.ts in the split, so point the read there. The
assertion's intent is unchanged.
2026-07-28 01:48:23 +00:00
PerishFireandGitHub 3f670090d7 ci: narrow daemon core merge validation (#6126)
* ci: narrow daemon core merge validation

* ci: preserve runtime definition shadow
2026-07-27 15:51:57 +00:00
Tom HuangandGitHub ad5a7d6ba1 Revert "feat(web): add guided inspiration and deliverable workflow (#5899)" (#6120)
This reverts commit 340cbb9b94.
2026-07-27 14:02:48 +00:00
PerishFireandGitHub 9db0d308e5 ci: establish guard library boundary (#6119) 2026-07-27 13:19:58 +00:00
PerishFireandGitHub 3aa1051ae8 refactor(desktop): extract release-feed interpretation into updater/feed (#6113)
Mechanical move out of updater.ts: metadata fetch/parse, per-channel
version resolution, artifact selection with the payload-to-installer
fallback, checksum resolution, candidate/release naming and matching,
the installed-outer version read, and the installer-reinstall floor move
to updater/feed.ts; numberField/objectField join updater/support.
updater.ts re-exports compareVersions, resolveInstalledOuterVersion and
remoteRequiresReinstall so existing import sites are unchanged. The two
pure feed test cases move to tests/main/updater/feed.test.ts; total case
count is unchanged.
2026-07-27 11:19:10 +00:00
PerishFireandGitHub 43a8a92eae ci: add daemon UI P0 capability shadow (#6112) 2026-07-27 10:54:44 +00:00
PerishFireandGitHub e5da903235 refactor(desktop): extract the update store into updater/store and shared updater/support (#6109)
Mechanical move out of updater.ts: the store layout/ownership machinery
(sentinel, owned-root validation, manual-clear rebuild, owned subdirs),
the persisted store metadata types with their guards, and the store path
constants move to updater/store.ts. Generic helpers they depend on
(createError, JSON guards, path containment, atomic JSON IO) move to
updater/support.ts for the remaining split slices to share. updater.ts
imports the same surface back; no exports change and no behavior
changes.
2026-07-27 10:46:46 +00:00
PerishFireandGitHub 9018be2173 refactor(desktop): extract updater config and scheduler into updater/ modules (#6106)
* refactor(desktop): extract updater env/config resolution into updater-config

Mechanical move of DESKTOP_UPDATE_ENV, the env validators,
resolveDesktopUpdaterConfig, and capabilitiesFor out of updater.ts into a
new updater-config module. updater.ts re-exports the public surface so
runtime wiring and existing imports are unchanged. The pure config test
cases move to updater-config.test.ts; behavior and total test count are
unchanged.

* refactor(desktop): extract the auto-check scheduler into updater-scheduler

Mechanical move of createDesktopUpdaterScheduler, its scheduler/silent
startup option types, and the scheduled-delay floor out of updater.ts.
updater.ts re-exports the scheduler surface so wiring in index.ts and
existing imports stay unchanged; the pure-mock scheduler test cases move
to updater-scheduler.test.ts. Behavior and total test count are
unchanged.

* refactor(desktop): house extracted updater modules in an updater/ directory

Move updater-config and updater-scheduler (sources and tests) into
src/main/updater/ and tests/main/updater/ so the split accumulates as a
directory instead of prefixed siblings. Pure renames plus import-path
updates; updater.ts keeps re-exporting the same surface.
2026-07-27 09:34:21 +00:00
Tom HuangandGitHub 70f3953079 fix(manual-edit): keep runtime targets selected when their last style declaration clears (#6098)
Clearing a runtime-only target's final declaration (e.g. toggling an active
alignment back to default) legitimately deletes its override rule, but the
style-save reconcile guard used rule ownership to recognize runtime-backed
targets, so the still-rendered target was classified as vanished: the save
dropped the selection and forced the full-reload canvas flash this path
exists to avoid. Runtime-backed is now a property of the document — the new
isManualEditRuntimeRenderedSource() consults the brand payload — independent
of whether the target currently owns an override rule.
2026-07-27 09:27:27 +00:00
PerishFireandGitHub 783391e9fa ci: narrow packaged leaf merge validation (#6104) 2026-07-27 09:12:28 +00:00
Ray XiandGitHub c3de4d5b95 fix(daemon): classify model and timeout failures (#6103) 2026-07-27 08:56:35 +00:00
PerishFireandGitHub a63eca6a4a fix(desktop): cover clear-cache in updater IPC teardown and host bridge guard (#6101)
* fix(desktop): include clear-cache in updater IPC teardown and host bridge guard

The od:update:clear-cache handler was registered but missing from
UPDATER_IPC_CHANNELS, so runtime teardown never removed it and a second
createDesktopRuntime() in the same process would throw on re-registration.
The host bridge structural guard likewise accepted an updater bridge that
lacks the clear-cache method, deferring the failure to call time.

Red specs: the boundary test now derives the teardown table from the
registered od:update:* handlers, and the host contract test rejects a
bridge missing clear-cache.

* refactor(desktop): deduplicate deferred-installer timeout and update action literals

The mac and Windows deferred-installer timeouts were two constants with
one value branched on platform; fold them into one. Route handle()'s
action dispatch through DESKTOP_UPDATE_ACTIONS instead of repeating the
string literals.

* docs(pack): correct the beta-s acceptance feed path to the betas channel

release-beta-s publishes RELEASE_CHANNEL=betas, so the internal feed
lives under betas/latest, not beta/latest.
2026-07-27 08:31:18 +00:00
PerishFireandGitHub cf3ca4fc3d ci: close packaged leaf test coverage (#6102) 2026-07-27 07:31:05 +00:00
PerishFireandGitHub fac10139c0 perf(ci): narrow zero-effect queue validation (#6100)
* perf(ci): narrow zero-effect queue validation

* docs(ci): keep scope spec state-focused
2026-07-27 06:33:06 +00:00
340cbb9b94 feat(web): add guided inspiration and deliverable workflow (#5899)
* feat(cli): add project rename command to CLI

Introduced a new command `od project rename <id> --name "<title>"` to allow users to rename existing projects. The command validates input and sends a PATCH request to update the project name in the backend. Updated CLI help documentation to include this new command.

* feat(web): enhance InspirationPicker with reference-site shortcuts and selection chips

Added functionality to the InspirationPicker component, allowing users to browse reference sites (e.g., Dribbble, Behance) directly from the picker. Implemented a selection chips feature that lists all current picks, enabling easy removal across different families. Updated styles for better visual representation of selected items. Enhanced internationalization support with new translations for the added features.

* feat(web): enhance InspirationPicker with detailed previews and selection management

Updated the InspirationPicker component to include a detailed preview feature for selected items, allowing users to view full documents directly from the picker. Implemented a "Selected" section that displays current picks with a remove option, improving user interaction. Adjusted styles for better visual consistency and added new translations for enhanced internationalization support.

* fix(web): restore uploaded inspiration thumbs and drop preview elapsed

Resolve locked inspiration-upload previews via the submitted path map so
answered forms still show real images, and keep the floating preview
status pill as a stage label only.

* feat(web): implement TaskDeliverableCard for displaying task outputs

Added a new TaskDeliverableCard component to showcase the primary deliverable and its associated outputs. This includes a preview feature for various file types, an actions menu for sharing and downloading, and improved styling for better user experience. Enhanced internationalization support with new translations for deliverable-related terms. Updated InspirationPicker to utilize the new deliverable ranking and searching functionalities.

* fix(inspiration): unify design system previews and source priority

* fix(web): align deliverable card regression coverage

* test(web): scope question form assertions

* fix(web): keep the deliverable card off failed and canceled runs

The card's status label is an unconditional Done, so gating it on the
shared terminal predicate let a failed or canceled run that wrote files
present a partial artifact as delivered while the same message reported
the error. Gate on the existing runSucceeded predicate instead; those
turns fall back to the plain file ledger, so the files stay reachable
without the false completion signal.

* fix(daemon): serialize DESIGN.md font stacks through a strict font-family grammar

extractFonts is deliberately permissive and its output was interpolated
verbatim into the generated <style> raw text, so a Body font value like
"Karla</style><img src=…>" could close the style element and inject
active markup into every auto-loaded card iframe. sanitizeFontStack now
rebuilds each stack from validated family names only (quoted names,
unquoted generic/system keywords), dropping anything else and falling
back to the trusted default stack; both the full preview and the compact
card renderer route every font interpolation through it. Card and
preview fixtures with a </style> payload pin the boundary.

* fix(daemon): ground additional inspiration systems in the run prompt

The picker's extra design-system picks reached the agent as ids on a
metadata line only, so a user-authored system contributed none of its
colors, fonts, or rules. The daemon now resolves each additional id
through the same DESIGN.md reader chain as the primary (workspace file
first, then registry), bounds the result (3 systems, 6000 chars each),
and composes an 'Additional inspiration systems' section with explicit
primary-wins precedence. Prompt tests pin a unique secondary token
reaching the composed prompt, both at the composer seam and end-to-end
through the chat route with bento's #FAD4C0.

* test(e2e): stabilize preview comment click

* test(web): update runtime override history expectation

---------

Co-authored-by: Amy <1184569493@qq.com>
2026-07-27 05:01:57 +00:00
b99a9fdc3d feat(manual-edit): add direct manipulation and reliable history (#5890)
* feat(web): manual edit v2 direct manipulation (v2.2–v2.4)

Selection overlay with action bar and drag/resize handles, floating text
toolbar with range-format highlight (queryCommandState round trip), Manus
color picker, image replace/crop/paste/drop, element copy/duplicate/delete,
and the systematized in-place content pipeline: every element-scoped patch
now reconciles the live iframe DOM from the saved source over
od-edit-apply-dom (replace/insert-after/append-child/prepend-child/remove)
with positional identity restamping, so commits, undo and redo never reload
the canvas, never flash, and never move the scroll position. Frozen-source
reloads remain only as a scroll-capturing fallback. Includes the Chromium
Home/End double-booking fix, the dblclick word-selection guard, and light
targets-broadcast dedupe.

* test(web): manual edit v2 unit and e2e coverage

Bridge (in-place apply ops, positional restamp, selection format state,
Home/End consumption, dblclick selection guard), source-patches (insert
readback, restore descriptors, sanitization), gestures/shortcuts/color
units, and host-level FileViewer suites proving content commits mutate the
canvas without a srcDoc reload, hand selection to inserted elements, and
record labeled manual versions for undo/redo. Also realigns the
manual-edit-history and srcdoc-reload-races helpers with the v2.1 opt-in
inspector two-step flow.

* docs(specs): manual edit v2 architecture spec

Six-layer map (identity/chrome/style/content/history/external-sync), core
invariants (DOM equals saved source without reloads; positional identity
restamps on structural change; every save is a labeled manual version),
patch-kind application matrix, performance contract, and the v2.1–v2.4
revision log including the real-browser verification round.

* fix(tools-dev): fail fast when a sidecar process dies during startup wait

waitForDaemonRuntime/waitForWebRuntime now accept a liveness probe for the
spawned pid, so a crashed daemon/web process surfaces immediately instead
of burning the full startup timeout.

* fix(web): edit brand-kit pages in place — no reload flash, no scroll jump

Brand-kit targets carry runtime-annotated ids with no markup of their own in
the saved source (edits persist into the payload / runtime overrides), so
the in-place readback came up empty and every commit fell back to a
srcDoc reload — the flash-and-jump-to-top the user hit when editing text
after an image. New od-edit-apply-dom op 'apply-content' mirrors the patch
fields (text/href/src/alt/html/attributes, on*/data-od-* filtered) onto the
live element instead, and set-outer-html reuses replace with the patch
html. The reload fallback's scroll restore also gains a clamped-only retry
ladder (600–4000ms) so async-rendering pages (brand kit renders after
load) no longer land at the top when a reload is genuinely needed.

* refactor(FileViewer): unify manual edit history management and enhance undo/redo functionality

This update introduces a consistent approach to managing manual edit history and undo/redo stacks by utilizing refs to mirror state. The new `updateManualEditHistoryStack` and `updateManualEditUndoneStack` functions ensure that the state remains in sync with the refs, preventing stale data issues during undo/redo operations. Additionally, the handling of in-session undo (Cmd+Z) has been improved to escalate to the host's global history when no local changes remain, ensuring a seamless user experience. Tests have been added to verify the correct behavior of these features.

* feat(manual-edit): enhance manual edit functionality with space scaling and improved gesture handling

This update introduces a new `ManualEditSpaceScale` interface to manage the scaling between viewport pixels and CSS pixels, ensuring accurate positioning during manual edits. The `manualEditMovePreviewTransform` and `manualEditResizeStyles` functions have been updated to utilize this scaling, improving the precision of drag and resize gestures. Additionally, the `ManualEditSelectionOverlay` component now maintains pointer capture during gestures to prevent interaction issues with nested iframes. Tests have been added to verify the correct behavior of these enhancements, ensuring a smoother user experience in manual editing scenarios.

* feat(FileViewer): add localized toasts for image upload process in manual edit

This update enhances the manual editing experience by introducing localized toast notifications for the image upload process. New messages for uploading, processing, and successful addition of images have been added to the i18n files. The `insertManualEditImage` function now manages these notifications, providing users with real-time feedback during image uploads. Additionally, tests have been implemented to ensure the correct display of these toasts across different locales.

* fix(manual-edit): drag whole image to move + lock selection frame to element box (#5888)

Two direct-manipulation fixes reported from real prototype/landing/deck edits:

1. Move by dragging the image body, not only the top pill. Adds a
   full-interior moveBody surface inside the selection frame that starts the
   same undoable move gesture; scoped to image targets so text/link bodies
   keep click-to-edit. Rendered under the resize handles so edges still resize.

2. Keep the selection frame locked to the element during resize. The frame
   previously drew the gesture-intent x/width and only adopted the iframe's
   measured y/height, so an element that re-centers, caps at max-width, or
   reflows on width change left the frame drifting horizontally off the
   picture. adoptMeasuredExtent now takes the full measured rect and
   displayRect follows it, so the chrome always wraps the element.

Adds ManualEditSelectionOverlay tests for body-drag move and measured-box
frame sync; records the change as spec v2.5.

Co-authored-by: Claude <noreply@anthropic.com>

* test(web): stabilize manual edit browser validation

* fix(manual-edit): address structural edit review blockers

* fix(manual-edit): preserve runtime formatting and restore order

* fix(manual-edit): flush toolbar styles before navigation

* fix(manual-edit): preserve runtime target identity

* fix(manual-edit): serialize saves and image handoff

* fix(manual-edit): clear stale runtime clipboard

* fix(manual-edit): scrub rich text identities

* fix(manual-edit): save inspector text after formatting

* fix(manual-edit): action-bar boundary avoidance, select-without-reflow, image paste shortcut (#5892)

Three edit-mode canvas fixes from user feedback:

1. Action bar no longer covers the element frame/handles. A small or
   edge-hugging element previously had its move pill and resize handles
   hidden under the floating action bar (clamped to the top), so it could not
   be moved or resized. New pure helper manualEditActionBarTop places the bar
   above the frame, flips it below when the element hugs the top edge, and
   keeps it inside the canvas; horizontal clamping already handles the side
   edges. Adds a data-placement attribute.

2. Selecting a text element no longer makes it jump/grow. The bridge fused
   'select' and 'enter inline edit' into one click, and making a deck text box
   contenteditable releases its line-clamp/height cap so it visibly reflows
   larger the instant it is selected. The first click now only selects (no
   contenteditable, no reflow); editing begins on a second click of the
   already-selected element or a double-click — matching how images/containers
   already select.

3. A selected image/container can be pasted with Cmd/Ctrl+V. The native paste
   event only fires while an editable element holds the caret, which never
   happens for non-text selections, so the shortcut did nothing for images.
   The bridge keydown handler now forwards od-edit-paste-request for a selected
   non-editable element (paired with the existing Cmd/Ctrl+C copy).

Updates the 14 inline-edit bridge tests to enter edit via double-click and
adds coverage for all three fixes; recorded as spec v2.6.

Co-authored-by: Claude <noreply@anthropic.com>

* fix(manual-edit): image corner scaling, nowrap unlock on resize, restore image paste

Three edit-mode canvas fixes from user feedback:

1. Images get four corner anchors that scale aspect-locked from any corner,
   anchored at the opposite corner (new resize-nw/ne/sw/se gesture kinds).
   The dominant pointer axis drives the scale, the floor binds the larger
   dimension, and corner gestures skip snapping so the ratio never breaks.
   Corner resizes persist width AND height (space-scale corrected) plus the
   offsets that keep the anchored corner fixed.

2. Resizing an element with white-space: nowrap (or pre) now unlocks
   wrapping (normal / pre-wrap) alongside the width — a narrowed heading
   previously stayed on one line and overflowed its own new box.
   ManualEditStyles and the bridge style props gain whiteSpace.

3. Image paste works again. The v2.6 Cmd/Ctrl+V keydown branch called
   preventDefault, which suppresses the native paste event — the only place
   clipboard image bytes are readable — so pasting an image did nothing.
   The shortcut now arms a 150ms one-shot element-paste fallback instead;
   any real paste event disarms it and routes image vs element itself, so
   the two channels never double-fire.

Adds gesture/overlay/bridge coverage for all three; recorded as spec v2.7.

* fix(manual-edit): replay runtime history in place

* fix(brands): reject scraped CSS junk font families before token emission

An extraction can capture CSS source text instead of a real font family
(e.g. Tailwind v4's `--theme(--default-font-family` from aliyun.com).
Interpolated raw into the kit's `--brand-font-family`, the unbalanced
parenthesis swallows every later :root declaration, so the component kit
renders unstyled (UA serif, collapsed buttons) while earlier color tokens
still work.

isRenderableFontFamily() now guards both emission seams: the seed's
fontStack (kit/variables/artifacts token block) and brandFontAssets'
display-family stack (h1-h3 face). Junk families drop out and the
renderable fallbacks + system stack take over.

* fix(manual-edit): replay runtime-only style history from the persisted override rule

Runtime-only brand-kit targets persist set-style patches in the
style[data-od-manual-edit-runtime-overrides] rule, not as element inline
styles. The in-place history replay read inline styles only, so redo of a
runtime style change replayed empty values while reporting success — the
file held the redone style while the canvas stayed on the undone one.

readManualEditSavedStyles() now reads a target's persisted styles wherever
they live (inline attribute for source-backed nodes, the runtime override
rule otherwise), and the set-style history branch replays through it. The
same inline-only read also made reconcileManualEditStyleSave() treat every
runtime style save as "target vanished" — erroring, dropping the selection,
and reloading the canvas — so it now consults
hasManualEditRuntimeStyleOverride() before taking that path.

Regressions: source-patches unit coverage for the saved-styles read and the
override predicate, plus a FileViewer spec that styles a runtime target,
undoes and redoes it without any srcdoc change, and asserts the redo
preview carries the persisted value (red on the previous head).

* fix(manual-edit): merge partial runtime style patches into the persisted rule

Successive debounced toolbar autosaves send only the touched property, but
setRuntimeStyleOverride() rebuilt the target's override rule solely from the
incoming patch, so a runtime-only brand-kit target lost its earlier saved
declarations (fontSize save, then color save -> font-size silently dropped).
Persistence now merges the incoming patch into the existing rule
declarations, treating empty incoming values as deletions and removing the
rule once its last declaration is deleted.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-07-27 04:09:02 +00:00
Marc ChanandGitHub 7787556cf1 fix(daemon): full ACP tool transcript and richer usage telemetry (#6057)
* fix(daemon): full ACP tool transcript and richer usage telemetry

Map all ACP tool_call frames to canonical tool_use/tool_result for
run.events, PostHog run_finished, and Langfuse spans. Preserve
artifact_count via Write/Edit normalization, tighten path extraction,
forward truncated results, and emit real tool startedAt.

Enrich usage scanning (thought_tokens, anthropic vs openai cache
semantics), canonical tool-family PostHog props, analytics recovery
finish snapshot, and shared content-tool redaction.

* fix(daemon): prefer ACP kind over noncanonical tool names

Normalize recognized ACP kinds (e.g. kind:read + name:read_file → Read)
before emitting tool transcripts so Langfuse content-tool redaction matches
canonical families and does not leak file contents.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): fail-closed redaction for unknown ACP tool payloads

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): flush open ACP tools as errors on session fail

When a session dies mid-tool (timeout, exit, RPC error), emit pending
tool_use/tool_result pairs with isError so transcripts stay complete.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): redact ACP Bash stdout in tool transcripts

Execute tools can dump private files (e.g. cat .env); replace Bash
tool_result content with a length summary before the canonical transcript
ships so Langfuse cannot receive raw execute output.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): redact Linux home paths in Langfuse Bash tool spans

Extend local-path masking for ACP Bash partial redaction to cover
/home and /root (not only /Users and Windows Users), so Linux home
paths do not leak into Langfuse tool inputs when content telemetry is on.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): redact custom ACP tool names before Langfuse telemetry

Sanitize path/token-like kind:other tool names at transcript emit and
canonicalize non-allowlisted names for Langfuse span labels, toolName
metadata, and redaction placeholders so untrusted custom names cannot
leak even when content telemetry is off.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* test(e2e): force-click unstable comment targets in preview iframe

UI P0 project-workspace timed out on comment attachment when Playwright
kept waiting for hero-title stability under auto-fit zoom / bridge inject.
Click once visible with force so the critical flow stays reliable.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): merge partial usage frames in reverse analytics scan

Keep provider_usage for thought/cache-only trailing usage events while
continuing the reverse scan to the latest primary input/output/total
record so run_finished and Langfuse do not drop complete token counts.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): flush open ACP tools before AMR no-output fail

Clean-flush pending non-think tools on successful session/prompt before
evaluating emittedConcreteToolEvent so missing terminal tool_call_update
does not mark a productive run as acp_no_visible_output.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): merge partial primary usage and flush tools on ACP abort

Require both input and output before ending the reverse usage scan so
output-only or input-only trailing frames still merge earlier counters.
Flush deferred open ACP tools as errored on abort so user-canceled runs
keep complete tool transcripts for Langfuse/PostHog.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): hash path-like ACP toolCallIds before telemetry

Adapters can embed user paths in toolCallId (e.g. read:/home/alice/.env).
Hash those values at tool_use/tool_result emit so Langfuse span ids and
metadata.toolCallId cannot leak secrets, while keeping the raw id as the
local frame-correlation map key.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): always hash ACP adapter toolCallIds for telemetry

Identifier-shaped secrets (sk-proj-*, ghp_*, JWTs) passed the prior
allowlist because they contain no path characters. Hash every non-empty
adapter toolCallId before tool_use/tool_result emission so Langfuse span
ids and metadata.toolCallId cannot leak tokens.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): keep reverse usage scan open for missing cache fields

When a newer usage frame already has input+output but omits cache
counters, continue scanning older frames so cache_read/cache_creation
still merge into run_finished and Langfuse.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): retain flushed ACP tool IDs against late terminals

Keep acpToolRunEventState entries after flushOpenAcpTools so a racy
tool_call_update cannot recreate the same id and emit a second
tool_use/tool_result pair after timeout, abort, or prompt flush.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): block kind:other Bash-like tool names

Custom ACP tools with kind:other must not emit Bash/shell/execute/terminal
names, which would unlock Langfuse partial redaction and leak rawInput.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)

* fix(daemon): fail closed on Bash names without execute kind

ACP tools missing kind must not preserve name/title Bash labels that unlock
Langfuse partial redaction; only recognized execute-family kinds may emit Bash.

Generated-By: looper 0.11.0 (runner=fixer, agent=grok-build)
2026-07-27 04:08:27 +00:00
f9a6e18c11 feat(ci): promote the certain-exempt docs core to merge-queue trust (#6047)
* feat(ci): promote the certain-exempt docs core to merge-queue trust

Split the exempt surface into a certain-tier core (docs/, apps/landing-page/,
.vscode/, .idea/, .github/ISSUE_TEMPLATE/, LICENSE, CODEOWNERS) and the medium
residue (global markdown regex, workflow exacts, nix). A merge-queue group
confined to the core now drops to the unconditional floor lanes instead of
running everything; replaying the last 398 first-parent merges puts that at
12.3% of queue traffic.

The promotion is backed by a new floor-lane guard check, "certain-exempt
surface consumption": no skippable-lane source may reference a certain-exempt
path (dot-relative literals flagged everywhere; bare repo-relative literals
flagged outside test fixtures). guard.ts gains --list-checks as the machine
registry, and the rule-table invariant test now requires every certain rule's
guard field to resolve to a live check.

* docs(ci): record the scope confidence methodology in specs/current/ci.md

The living framework for confidence-tier changes: medium-tier cheap loop vs
certain-tier deliberate loop, the three-sentence promotion discipline, guard
strength levels and floor placement, evidence recipes (replay, offline plan,
queue trace extraction), tooling graduation criteria, and the open questions
deliberately left undecided. Indexed from AGENTS.md and .github/AGENTS.md
required reading.

* fix(ci): narrow certain-exempt fixture handling

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(ci): pin the trae-cli consumption exception to the daemon-lane wiring

The review round established that apps/daemon/tests/runtimes/trae-cli.test.ts
genuinely reads docs/agent-adapters.md. Its exemption from the consumption
guard was justified by a wiring fact (the ci.yml daemon lane runs only
project-watchers.test.ts) stated as prose, which would rot silently if the
lane ever widened. Make the exception conditional on that exact ci.yml needle:
when the daemon lane changes, the exemption disappears and the guard reports
the read, forcing reclassification instead of trusting a stale rationale.

* docs(ci): codify exception-precondition binding in the methodology

Backfill the pattern the first review round produced: guard allowlist entries
justified by local definitional facts may stay prose, but entries justified by
remote mutable facts (lane wiring, gate topology) must be conditional on a
checked precondition so the exception dies loudly with its premise. Records
the trae-cli/daemon-lane needle as the worked example.

* fix(ci): fold static paths in exempt consumption guard

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(ci): require exclusive daemon test wiring

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(ci): recognize daemon pnpm selector forms

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(ci): tokenize daemon workflow test commands

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-07-27 03:22:21 +00:00
netteeandGitHub de2020fb88 docs: reconcile code-evolution drift (#6083)
* docs: reconcile code-evolution drift

* fix(web): preserve generic-disconnect recovery retries

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(web): retry capped reattach probe after cleanup

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)
2026-07-27 03:03:45 +00:00
40a35b7786 feat(landing): add Codex Slides sister-product page (#6050)
* feat(landing): add Codex Slides sister-product page

Add /codex-slides/ under the Product menu next to HTML Anything and
HTML Video, for the open-source AI slide studio nexu-io/codex-slides.

- Reuses the sibling product-page shape (hero, at-a-glance band, ideas,
  numbered flow, deck gallery, product-UI gallery, scenarios, export
  spec, Fast mode + install, closing CTA band).
- Full 11-locale copy: English base + Agent translations, metadata and
  body localized; JSON-LD (SoftwareApplication + Breadcrumb + FAQ) uses
  the localized page URL.
- Closing CTA reuses the shared .dbfinal painted band and leads with the
  Open Design desktop download; ghost CTA stars the Codex Slides repo.
- Wires the entry into the Product mega-menu and the footer product
  column; ships local webp screenshots (no R2 upload step).

* fix(landing): give the Fast mode / Install block its own section heading

The two-up Fast mode + Install in Codex notes had no heading of their
own, so they read as if they belonged under the preceding export section.
Wrap them in a proper section titled duoTitle (Fast and frictionless)
with the two notes demoted to sub-headings.

---------

Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com>
2026-07-26 07:50:28 +00:00
Ray XiandGitHub 99c13e083e fix(daemon): preflight incompatible Codex models (#6036)
* fix(daemon): preflight incompatible Codex models

* fix(daemon): fail open for layered Codex config

Detect system and enterprise config layers before rejecting a known-old Codex model, and recheck cloud config after the auth probe.

Isolate the capability integration suite from inherited Codex auth and endpoint variables with case-insensitive snapshot and restore coverage.

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)
2026-07-24 09:14:00 +00:00
a2ba3ee2ad feat(updater): manual cache clear, installer-reinstall floor, and crash-recovery lifecycle (#6032)
* feat(updater): manual cache clear + installer-reinstall floor on the installed outer version

Two disaster-recovery capabilities for the packaged updater:

- Reuse control.launcher.version.min properly: the gate now compares the
  physically installed outer package version (read at check time from the
  outer bundle's open-design-config.json via the launcher launch path;
  OD_UPDATE_INSTALLED_VERSION overrides for tests), not the running payload
  version. When the floor trips - or min is set but the outer version is
  unreadable (conservative) - the updater selects the installer artifact and
  offers a same-version installer reinstall when no newer release exists
  (clamped to min <= candidate so the offer always converges). The status
  snapshot carries a reinstall block {reason, installedVersion, minVersion,
  url}; UpdateDialog/UpdaterPopup render reinstall copy with an optional
  operator jump link. tools-release publish-metadata publishes the block from
  RELEASE_LAUNCHER_VERSION_MIN(_URL) (per-channel repo vars with a _STABLE
  fallback wired in all release workflows) and hard-fails when min exceeds
  the release version; verify-metadata re-checks the published block and
  summary-metadata surfaces the floor.

- Manual clear-cache action (od:update:clear-cache IPC, sidecar clear-cache
  action, Settings > About row with a two-stage inline confirm): resets
  one-shot update state (downloaded release, install freeze) back to idle,
  purges releases/staging/downloads/.back, removes a stale launcher
  attempt.json plus any non-confirmed desktop-handoff journal, and deletes
  non-retained payload versions. Runtime active/lastSuccessful versions,
  retained cleanup entries, install.json, and a confirmed handoff journal
  are never touched; locked files defer through the existing cleanup.json
  retry machinery.

Also: tools-pack --update-action now validates through sidecar-proto's
exported isDesktopUpdateAction so clear-cache reaches the ops surface;
tools-serve updater fixture gains control min/url knobs and CLI flags;
9 new i18n keys across all 19 locales; tools/pack/AGENTS.md documents the
gate semantics and clear-cache boundaries.

Validated locally per the updater matrix (desktop/web/tools-serve/tools-pack
suites, guard, typechecks) plus a mac release-beta closed loop: platform full
spec, same-version reinstall against a real outer/payload version split,
clear-cache recovery, and a real-feed payload update to 0.15.1-beta.4.

* test(updater): close Windows recovery acceptance

* test(updater): mirror Windows same-version reinstall recovery on the mac lane

Port the Windows runSameVersionUpdaterRecoveryAcceptance shape into the mac
full profile: after the payload cold-start acceptance, restart the packaged
app against a fixture publishing an installed-outer floor at the running
payload version and assert the same-version installer reinstall snapshot
(reason/installedVersion/minVersion/url), the popup reinstall learn-more
link, clear-cache back to idle with launcher pointers untouched, explicit
re-check recovery, and the installer open in dry-run mode — macOS has no
silent DMG install to execute, unlike the Windows NSIS transaction lane.
Extends the popup eval expression/validator with reinstallLinkVisible and
records an updaterRecovery block in the smoke summary. Full-profile test
timeout raised 240s -> 360s for the extra app restart.

Validated locally: release-smoke full profile green in 80s with the recovery
summary populated (reinstall block exact, cleared idle, recovered dmg,
dryRun install).

* refactor(release): centralize launcher version floor channel policy in one resolver

Channel policy for control.launcher.version.{min,url} is now managed as one
repo-vars pair per channel (RELEASE_LAUNCHER_VERSION_MIN[_URL]_<CHANNEL>).
Workflows pass the channel pair plus the STABLE pair through verbatim — the
|| fallback expressions are gone from YAML — and the shared resolver in
tools/release/src/storage/launcher-version-floor.ts owns resolution and
validation: pair-level stable fallback for non-stable channels (never mixing
one channel's min with another's url), version format, http(s) url, orphan
url rejection, and the floor <= releaseVersion guard. publish-metadata and
verify-metadata consume the same resolver, so verify re-derives the expected
block from the same channel policy instead of trusting a pre-resolved env.
release-workflows.test.ts pins the verbatim passthrough keys in all five
release lanes and rejects any reintroduced YAML fallback.

* feat(updater): let clear-cache rebuild a provably-owned corrupt update store

A corrupt store is one of the blocking scenarios the manual clear exists to
recover from, yet the action previously bailed on the very store errors it
should heal. clear-cache now rebuilds the update root when — and only when —
ownership is provable: the current-generation sentinel is the proof, and
everything else inside an owned root is updater cache by definition. Roots
without a sentinel, with a foreign-generation marker, or failing IO are never
touched; the original store error surfaces unchanged. Four specs pin the
boundary (corrupt metadata rebuilt, stray entries rebuilt, unowned root
refused with files intact, foreign-generation marker refused).

* fix(launcher): pre-arm delegated payload launches so pre-bookkeeping crashes roll back

A payload that spawned successfully but died before reaching its own launcher
bookkeeping left no attempt.json behind, so every later cold start re-selected
the same broken active pointer and re-delegated to the dead payload — a
permanent dead loop the installer fallback could never surface (found while
designing the crash-rollback acceptance).

The delegating parent now arms attempt.json BEFORE spawning the payload and
passes the pointer as --od-launcher-delegated-* argv. Selection gains an
active-delegated reason: an attempt matching active AND the delegated pointer
is the launch in progress, not a previous failure; only an exact active match
qualifies, so a stale pointer cannot defeat the rollback. Rollback
(last-successful) delegations deliberately carry no marker and never re-arm —
the attempt on disk IS the rollback evidence the child must re-derive.

Covered end to end: packaged outer delegation pre-arms (and skips pre-arm on
rollback), the updater's payload activation pre-arms and threads the pointer
through the deferred relaunch, and confirm clears the attempt for delegated
launches. launcher-proto 18, packaged 237, desktop 264 all green.

* fix(updater): scrub a stale payload install freeze after a rollback

A payload install freezes the updater with installResult.activeVersion
awaiting the relaunch. When that payload crashed and the launcher rolled
back, the app restarts on the OLD version with the freeze still persisted —
every later check became a frozen no-op, so a rolled-back install never saw
another update offer (the crash-rollback acceptance exposed this in its
self-heal phase). Cold-start restore now detects the broken promise —
installResult.activeVersion newer than the running version on a live process
— and drops the freeze and stale install result while keeping the verified
downloaded release actionable. The installer-artifact freeze (no
activeVersion) keeps its existing restore semantics. Red spec:
'clears a stale payload install freeze when the promised relaunch never
became the running version'.

* test(updater): full-lifecycle acceptance — silent startup, crash rollback, coverage map

Two new packaged acceptance tests on both platform lanes (mac validated
locally; win symmetric for the Windows box):

- 'applies a downloaded payload silently on the next cold start': enables the
  daemon-owned allowSilentUpdates through the production GET+PUT
  /api/app-config path, restarts, and asserts the first scheduler tick
  installs, quits, and relaunches with converged pointers — no updater action
  issued.
- 'rolls back a crashing payload and self-heals on the next good update':
  repacks the real payload archive with a crash-before-bookkeeping stub
  (mac: shebang script via ditto; win: a real executable — System32 where.exe
  — via the installed app's bundled 7z, since a script cannot stand in for an
  exe), drives the update through the popup, asserts the pre-armed attempt
  survives the crash as rollback evidence, cold-starts into the rolled-back
  base version (degraded steady state pinned: broken pointer stays active
  with its attempt), then self-heals via a version-bumped healthy payload —
  real recovery releases ship as version+1.

Spec hygiene: resetPackagedRuntimeState wipes launcher/runtime/daemon state
before each lifecycle test (uninstall keeps runtime data by design, and
leftover pointers silently delegate fresh installs onto stale payloads);
mac waitForHealthyDesktopVersion gains win's requireSettledLauncher opt-out
for rollback waits.

docs/testing/updater-lifecycle.md is the new lifecycle-to-test coverage map
(incl. deliberate manual-only nodes), linked from tools/pack/AGENTS.md and
the e2e coverage status doc.

* fix(updater): harden Windows full-lifecycle acceptance

* test(release): make channel-prepare hermetic against local git tags

prepare-preview derives its latest-stable floor from the clone's real
open-design-v* tags, so the channel-prepare tests were green on tagless CI
checkouts but permanently red on any developer clone once shipped stable
tags advanced past main's package version (0.15.1 vs v0.15.1/v0.16.0 today).
The spawned scripts now run with GIT_DIR pointing at a throwaway repo
holding exactly the tags each test declares, and a new negative case pins
the floor rejection itself (packaged version below a v99.0.0 stable tag).

* test(e2e): model delegated payload launch

Pass the updater's pre-armed payload pointer into the cross-runtime launcher simulation so it represents the spawned payload process instead of a later crash-recovery launch.

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* test(web): wait for question form readiness

Wait for the asynchronously derived submit-disabled state before asserting it, removing the suite-order race observed by the Web workspace tests check.

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(updater): preserve recovery state across locks and restarts

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-07-24 05:18:48 +00:00
14fcc411cd feat(ci): confidence-tiered scope rule table with merge-queue shadow evaluation (#6029)
* chore(scripts): make root scripts/ test-free and purify the guard entrypoint

Root scripts/ is now source-only, enforced by a new "scripts test-free"
guard check (any *.test.{ts,tsx,js,jsx,mjs,cjs} under scripts/ fails
pnpm guard). The root guard script becomes a pure tsx ./scripts/guard.ts
invocation instead of chaining a hand-maintained node --test file list.

Script behavior-contract coverage follows the boundary e2e/AGENTS.md
already declares for e2e/tests/scripts/: the fork PR approval security
tests migrate there (converted to Vitest, 24 tests passing), and the
remaining script unit tests are deleted — five of them (batch-design-
system-test, check-design-system-package-quality, plugin-previews-diff,
plugin-previews-gc, migrate-to-plugins/example) were orphans no runner
ever executed; the guard-chained checker tests covered logic whose
repo-wide enforcement remains in guard.ts checks. Coverage with a real
test claim gets rebuilt in e2e/tests/scripts/ on demand.

* test(ci): pin characterization goldens for scopes.ts scope detection

Golden tests run scripts/scopes.ts as a subprocess exactly the way ci.yml
does, with gh stubbed through the existing OPEN_DESIGN_GH_NODE_SCRIPT seam
(hermetic stub materialized per run), and pin the complete 20-key output
plan for a matrix of changed-file sets across pull_request,
workflow_dispatch (hot/full), and merge_group events.

They deliberately pin current quirks (skills/*.md arming daemon+web without
the ui-critical fallback; e2e/ui/*.md arming ui_p0 with workspace validation
off; dispatch-hot skipping the workspace_validation re-derivation) so the
upcoming rule-table restructuring can prove behavior preservation
byte-for-byte.

* refactor(ci): restructure scopes.ts into a confidence-tiered rule table

Scope detection becomes data plus a pure evaluator: every changed file is
classified by an additive rule table (union of matched effects, minimum
confidence across matched rules), and an evaluation context brings a trust
threshold — files below it, or matching no rule, escalate fail-closed to
the full radius. Today's behavior is exactly the degenerate case of this
structure (all rules medium, certain set empty): pull_request/hot believes
everything, the merge queue believes nothing and stays full. The
characterization goldens pass unchanged, byte-for-byte.

The exempt surface becomes an explicit empty-radius rule instead of a
special case, so exemptions can be split, rated, and promoted per rule.
Promotion to "certain" requires a guard field naming the enforcing check
(enforced by a rule-table invariant test).

New offline entry points for rule iteration: `plan --context
pr|merge-queue|full --files ...` evaluates without any GitHub environment
and prints { plan, trace }; `rules` lists the table. Every evaluation now
returns a decision trace (per-rule hit counts, per-file escalations, and
an ifTrustAll shadow plan that shows what medium-confidence rules would
have allowed — the evidence stream for future certain-tier promotions);
github-output mode logs it and writes a step-summary table without
touching the frozen 20-key output contract.

The legacy dispatch-hot asymmetry (no workspace_validation re-derivation)
is preserved behind an explicit option and pinned by the goldens.

* feat(ci): evaluate merge-group union diffs at the certain threshold with shadow trace

The merge queue now resolves the queued group's union diff
(compare base_sha...head_sha from the merge_group event payload) and
evaluates it through the rule table at the "certain" trust threshold.
While the certain rule set is empty every file escalates and the queue
keeps running everything — the goldens pin this byte-for-byte — but the
evaluation's ifTrustAll shadow column now records, for every queued
group, what medium-confidence rules would have allowed: the evidence
stream that future certain-tier promotions will cite.

Queue lanes derive from the evaluated outputs (ci_mode stays reported as
"full", but lanes are no longer unconditionally forced), so promoting a
rule to "certain" later is a pure rule-table change with no further
structural work.

Fail-safe behavior is explicit and tested: resolution errors and empty
resolutions fall open to the full plan without failing the scopes job
(queue throughput must never depend on this evaluation), while
pull_request resolution failures keep failing the run as before.

Changed-file resolution no longer filters out removed files (manual hot
runs previously did): deleting a runtime source file must trigger the
same validation scopes as editing it. This is the only behavior change,
and it is strictly fail-closed.

* fix(ci): preserve guard contracts and fail closed on compare limits

Restore the eight guard behavior suites in the e2e script lane and make merge-group compare resolution treat GitHub's 300-file ceiling as incomplete.

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(ci): enforce extension-agnostic script test boundary

Match every suffix after .test. and cover TypeScript, MTS, and non-test filenames in the e2e script suite.

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

* fix(ci): route script contract tests to e2e

Ensure changes under e2e/tests/scripts arm E2E Vitest with the same daemon and web scope effects as their root script counterparts, and pin the behavior with a PR golden.\n\nGenerated-By: looper 0.11.0 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-07-24 05:18:39 +00:00
PerishFireandGitHub 83f3d57081 fix(web): remove preview run status overlay (#6027) 2026-07-24 04:26:32 +00:00
PerishFireandGitHub 702d6f3a0a fix(ci): make static gate runner-independent (#6039) 2026-07-24 04:49:21 +00:00
f2760fdf33 feat(landing): curated Codex design plugin catalogue (50 entries) (#5978)
* feat(landing): add curated Codex design collection under /plugins

Add a standalone /plugins/codex-design/ collection of the best real,
external skills for doing design with OpenAI Codex (openai/skills,
MengTo/Skills), positioning Open Design as the home for designing with
Codex and driving to the client download + the awesome-codex-design list.

- New collection page + 6 flagship skill detail pages (+ locale wrappers)
- Featured Codex design banner on the /plugins hub
- Editorial content in _lib/codex-design.ts (every entry links to source)
- On-brand illustrations (Figma-selection language) for hub cover, hero,
  and each skill

English baseline; per-locale copy layered in a follow-up.

* fix(landing): center Codex design collection + kill oversized section gaps

The collection page rendered full-bleed against the left edge and the
global `section { padding: 130px 0 }` rule blew the vertical gaps wide
open on both the collection and detail pages. Constrain the collection
to the shared 1180px safe area, neutralize the section padding on both,
and de-duplicate the hero eyebrow.

* style(landing): align Codex design collection to the site's editorial card DNA

The collection reinvented a soft, rounded, coral-accented card style that
clashed with the rest of /plugins/*. Rebuild it on the established
system: reuse the tpl-card DNA (1.5px ink border, hard offset hover
shadow, media bleed, mono uppercase labels, dark full-width CTA), the
shared .plugins-* hero primitives, and the ink/bone palette. Move the
skill grid to a global .codex-skill-grid (a scoped rule failed to apply),
fix the cramped detail-page related cards to full tpl-cards, drop the
off-palette coral from UI chrome, and de-duplicate the hero eyebrow.

* style(landing): make Codex design skill grid 4-up

Denser 4-column grid (was 3), matching the plugin hub's explore grid;
detail-page related row stays 3-up. De-dup the hero eyebrow.

* style(landing): regenerate Codex design illustrations brighter and punchier

The first pass read washed-out and samey at card size. Regenerate all
eight (hub cover, hero, six skill covers) with vivid acid-green + coral
accents, higher contrast, and crisp ink outlines so the covers pop in
the 4-up grid and match the site's acid-green accent.

* feat(landing): curated Codex design plugin catalogue (50 entries)

Rebuild the /plugins/codex-design collection from 6 placeholder entries into
50 curated, real, installable design skills and plugins for Codex and other
coding agents.

Each entry carries copy grounded in the upstream SKILL.md, its source repo,
star count, licence, a Codex-compatibility note, and a traction signal
(GitHub stars plus X/YouTube), cross-checked across GitHub, X and YouTube.

- 50 flat /plugins/<slug>/ routes with per-locale wrappers (11 locales)
- 50 covers: 14 upstream first-party showcase images, 36 generated
- collection page gains a category filter; detail card shows stars, traction,
  and a bundle note for multi-module entries
- 13 generic sub-command names disambiguated as 'Parent - Subname'
- full 11-locale localisation of UI and all 50 bodies
- README refresh plus new hero for the codex-design repo lives separately

Licence discipline: openai/skills (no root LICENSE), anthropics/skills (no
LICENSE), MengTo demo imagery (third-party sourced) and design-dna imagery
(real third-party sites) were all excluded.

* chore(landing): trigger landing CI (no-op comment)

* fix(landing): address review on the Codex design catalogue

Copilot review follow-ups:
- drop the committed GitHub repo-stats snapshot (data, lib, and fetch
  script). It carried an openai/skills row that contradicted the stated
  licence discipline, and a checked-in stats file goes stale silently.
  The detail card now shows only the star count that lives with the
  catalogue entry itself.
- remove the unused sourcePath frontmatter local (dead code).
- drop the .codex-related .codex-skill-grid override; the related row
  renders under .dbrelated, so the selector never matched.
- the filter chip bar is a plain filter, not a tab set: role=group
  instead of role=tablist, which promised tab semantics the buttons
  never implemented.
- fix the stale route in the hallmark page header comment.
- delete the detailForks / detailContributors / detailUpdated i18n keys
  that the removed stats card was the only consumer of.

* style(landing): let the source card stat row flow by column

The row now carries a single stat, so a fixed three-track grid was
describing a layout that no longer exists.

* fix(landing): stop tracking the landing-page node_modules symlink

A local symlink named node_modules was committed with the catalogue: the
root ignore rule is `node_modules/`, and a trailing slash matches only
directories, so a symlink of that name slipped past it. It pointed at an
absolute path on the author's machine, so every CI job died in setup —
pnpm cannot mkdir through a dangling link:

  ENOENT: no such file or directory, mkdir '.../apps/landing-page/node_modules'

Untrack it and drop the trailing slash so the rule covers a file or
symlink of that name too.

* fix(landing): drop the Figma category and announce the active filter

Review follow-ups on the Codex design catalogue:

- The catalogue has no plugin that reads Figma. The official Figma
  skills are excluded on licence grounds, so the sole entry filed under
  "Figma to Code" was image-to-code, an image-first workflow that
  generates its own reference images and never connects to Figma. The
  chip therefore promised "read a real Figma design" and led to a
  plugin that cannot do it. Move that entry to Frontend & UI, drop the
  category from the union type, the filter, and the copy, and reword the
  lede and intro from three jobs to two.
- Announce the filter state: the selected chip lived only in the visual
  is-on class, so a screen reader heard plain buttons and could not tell
  which filter was active. Initialise aria-pressed and keep it in step
  with is-on in the click handler.
- The locale files still advertised the old "6 plugins / 3 workflows"
  figures from the six-entry version; correct them to 50 and 13 across
  all ten.

* fix(landing): put the catalogue's source-card prose into English

Follow-ups from the second review pass:

- codexNote, social, and bundle are rendered verbatim by the detail
  template, but 57 of those values were written in Chinese, so English
  and every other locale showed strings like 'README 提 Codex ×8' on the
  source card. Translate them in place; the data module is the English
  source these pages fall back to.
- The plugin hub banner still sold 'Figma pipelines' in all eleven
  locales after the category was dropped. Reword it to match.
- The jobs band allocated three fixed desktop columns and now holds two
  entries, leaving an empty third. Flow one equal column per category so
  the band tracks whatever CODEX_COLLECTION.categories holds.

* fix(landing): name the catalogue cover links for screen readers

The cover image is decorative (alt=""), so the only text left inside
each card's media link was the category chip: all 37 frontend covers
announced as "Frontend & UI" and all 13 system covers as "Design
Systems", with no way to tell which plugin a link opened. Label each
link with the localized skill name, matching what the shared
template-card already does, on both the collection grid and the related
row of the detail page.

---------

Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com>
2026-07-23 14:34:00 +00:00
PerishFireandGitHub 657fb09f3a revert(pack): restore working Windows installer (#6008) 2026-07-23 11:41:17 +00:00
Chanhyo JungandGitHub 506c2900b9 fix(message-center): guard invalid published dates (#6007) 2026-07-23 07:16:15 +00:00
PerishFireandGitHub ff445a7a43 fix(web): remove duplicate preview run elapsed (#6005) 2026-07-23 05:15:22 +00:00
open-design-release-bot[bot]GitHubopen-design-release-bot[bot] <open-design-release-bot[bot]@users.noreply.github.com>
ca4ecf0bf2 chore(release): bump main to 0.16.1 ahead of stable 0.16.0 (#6000)
Co-authored-by: open-design-release-bot[bot] <open-design-release-bot[bot]@users.noreply.github.com>
2026-07-23 03:15:11 +00:00
Chanhyo JungandGitHub 2f1778752e feat(mcp): add Raven installer target (#5969) 2026-07-23 02:48:11 +00:00
Pavel CherkashinandGitHub 99bc3d60d9 fix(web): dedupe project workspace tabs on repeated open (#5993)
* fix(web): dedupe project workspace tabs on repeated open

The openWorkspaceTab event handler unconditionally appended a new tab on
every project-open event, so reopening the same project stacked duplicate
tabs instead of focusing the existing one. Mirror the dedup logic already
in syncStateToRoute: when a project tab with the same projectId exists,
update its conversationId/fileName/lastActiveAt and activate it rather
than appending.

Fixes #2641

* fix(web): coalesce duplicate project tabs on workspace restore

normalizeTabsState deduplicated entry tabs and tab ids but not project
tabs sharing a projectId, so workspaces persisted before the dedupe fix
restored with their pre-existing duplicate project tabs still visible.
Coalesce project tabs by projectId in normalizeTabsState (keep the active
match, else the newest), mirroring the entry-tab dedupe. This repairs
affected persisted state on restore, not just new corruption.

Adds a restore regression with two distinct tab ids for the same project.

Follow-up to #2641 / review feedback on #5993
2026-07-23 02:47:35 +00:00
Abhishek SarkarandGitHub 034c3895d1 fix(web): hide empty tool_call/tool_call_update status rows (#4621)
buildBlocks() in AssistantMessage filters a fixed list of internal status
labels before they reach StatusPill, but tool_call / tool_call_update are
not in it, so they fall through and render as raw, expandable status pills
with no tool name, input, output, or detail — looking like "a tool ran but
produced no output".

These are transient ACP markers: on the live SSE path the daemon already
normalizes them to `running` (TRANSIENT_ACP_STATUS_LABELS in
providers/daemon.ts), which buildBlocks() skips. The persisted-events path
does not normalize, so the bare labels survive into the UI. Add both labels
to the existing skip list, with a comment pointing at the daemon source of
truth.

Add a red-spec test asserting the two empty status rows render no pill, plus
a guard that status rows carrying a real detail still render.
2026-07-22 14:36:07 +00:00
AmyandGitHub 3162da5f23 test: cover runtime automation gaps (#5976)
* test: cover runtime automation gaps

* fix: remove duplicate runtime startup declarations

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)
2026-07-22 14:29:34 +00:00
PerishFireandGitHub 910e5d3387 docs: add 0.16.0 release notes (#5979)
* docs: add 0.16.0 release notes

* docs: make 0.16.0 notes user focused
2026-07-22 12:45:14 +00:00
netteeandGitHub adbb0ff9a4 fix(message-center): honor active AMR profile for anonymous sync (#5968)
* fix(message-center): honor active AMR profile for anonymous sync

* fix(vela): keep control context on one config snapshot

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)
2026-07-22 08:45:24 +00:00
dcdb0c4204 fix packaged updates after payload cwd cleanup (#5967)
* fix packaged payload startup after cwd cleanup

* fix deferred installer helper cwd

Generated-By: looper 0.11.0 (runner=fixer, agent=codex)

---------

Co-authored-by: Looper <looper@noreply.github.com>
2026-07-22 08:15:45 +00:00
jaehanbyunandGitHub 2337932714 feat: expose GPT-5.5 Fast service tier (#4287)
* feat: support Codex service tiers

* fix: forward service tiers through MCP runs

* fix: clear default service tier selections

* fix: preserve service tier on model option updates

* fix: preserve service tier without explicit model

* fix: preserve service tier in connection tests

* test: stabilize API empty stream UI check

* fix: preserve codex service tier labels

* fix: preserve service tier without saved model

* fix: address service tier review follow-ups

* fix: pin legacy chat assistant rows before start

* fix: accept bare model catalog responses
2026-07-22 07:11:03 +00:00