Files
onyx/web/lib/opal
Wenxi ad9c0030e9 feat(craft): simplify scheduled task details and plugin controls (#16408)
## Description

<img width="1014" height="660" alt="Screenshot 2026-10-21 at 12 10
14 PM"
src="https://github.com/user-attachments/assets/d885f4ef-8d88-49ee-aab8-4245e755a75b"
/>
<img width="1014" height="1200" alt="Screenshot 2026-10-21 at 12 10
03 PM"
src="https://github.com/user-attachments/assets/14b6d481-8d11-4d4d-b267-1b9cb9d2926f"
/>


fixes:
https://linear.app/onyx-app/issue/ENG-4406/runs-of-an-existing-scheduled-task-are-hard-to-find


Make scheduled tasks easier to inspect and edit. The detail page now
puts a compact prompt preview and enabled plugin labels above run
history. Its header keeps Edit, Run once, and Pause or Resume visible.

The editor groups schedule controls in a panel and replaces the app list
with plugin cards. Connected, enabled cards have a white background.
Disabled cards use the gray surface. Disconnected cards show an orange
dot and a connect button instead of the enable toggle. Clicking a card
opens action settings or the shared connection dialog.

Keep task drafts and modal selection in the editor, with separate
components for cards, action edits, and the read-only summary. Missing
connection data cannot enable a plugin. Editing actions before first
enabling now preserves untouched personal defaults. Update all nine
translations and the feature map.

## How Has This Been Tested?

- 33 tests across task policies, the summary, detail page, task form,
and schedule helpers.
- 9 translation catalog tests.
- TypeScript type and coverage checks, lint, formatting, translation
checks, and feature-map integrity.
- Playwright browser checks at desktop and mobile widths: prompt
expansion, edit navigation, schedule inputs, plugin toggles, connection
modal, card backgrounds, hover, and pointer cursor. No horizontal page
overflow.
- Browser checks used intercepted fixture data. No real scheduled run or
external OAuth sign-in was performed.

## Additional Options

- [x] [Optional] Please cherry-pick this PR to the latest release
version.



<!-- This is an auto-generated description by cubic. -->
---
## Summary by cubic
Redesigns the scheduled task detail page and editor so tasks are easier
to inspect and edit. The detail page now shows an expandable prompt
preview and enabled plugin labels above run history, with no tabs, and
the header keeps Edit, Run once, and Pause or Resume visible.

Plugin editing
- The app list is now a grid of plugin cards: connected and enabled
cards use a white surface, disabled cards use the gray surface, and
disconnected cards show an orange dot with a connect button.
- Clicking a connected card opens its action settings even when the
plugin is disabled for the task; clicking a disconnected card opens the
shared connection dialog.
- Disconnected plugins can still be disabled, but missing connection
data blocks their action settings.
- First edit or enable snapshots personal defaults, including untouched
actions, so they survive an enable toggle.
- Splits the editor into `TaskPluginCard`, `TaskAppActionsModal`, and
`TaskActionPoliciesSummary`, and updates all nine translations and the
feature map.

Schedule and load handling
- The schedule editor now groups controls in a panel and notes that
times use the local timezone.
- Action-policy load failures show an error with a retry button, and the
detail page links to Edit instead of using a tab.

<sup>Written for commit d2575959fb.
Summary will update on new commits.</sup>

<a
href="https://cubic.dev/pr/onyx-dot-app/onyx/pull/16408?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="View guided diff"
src="https://www.cubic.dev/buttons/review-in-cubic-light.svg"></picture></a>
<a
href="https://www.cubic.dev/action/auto-fix/pr/onyx-dot-app/onyx/16408?returnTo=https%3A%2F%2Fgithub.com%2Fonyx-dot-app%2Fonyx%2Fpull%2F16408&source=description"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"><img
alt="Turn on auto-fix"
src="https://www.cubic.dev/buttons/turn-on-auto-fix-light.svg"></picture></a>

<!-- End of auto-generated description by cubic. -->





<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
<!-- coderabbit-ai-generated:v1 -->

## Summary by CodeRabbit

- **New Features**
- Redesigned scheduled-task details with collapsible prompts, run
history, status controls, editing, one-time runs, and deletion actions.
- Added plugin cards, connection flows, enablement controls, and
action-policy editing with unsaved-change protection.
- Added clearer interval, daily, and weekly schedule editing with
local-time guidance.
  - Added retry handling for action-policy loading errors.

- **Improvements**
  - Added configurable tag sizes for compact or standard displays.
  - Updated terminology and translations across supported languages.

- **Documentation**
  - Expanded guidance for scheduled-task screens and plugin behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-10-21 21:01:09 +00:00
..
…

Opal

Onyx's TypeScript component library and design system.

Install

bun add @onyx-ai/opal

Peer dependencies (install whichever the lib actually exercises in your usage):

bun add react react-dom next \
  @radix-ui/react-popover \
  @radix-ui/react-slot @radix-ui/react-tooltip \
  @dnd-kit/core @dnd-kit/sortable @dnd-kit/modifiers @dnd-kit/utilities \
  @tanstack/react-table formik \
  react-markdown remark-gfm rehype-sanitize

Setup

1. Import the design tokens once

In your app's root entry (e.g. Next.js app/layout.tsx):

import "@onyx-ai/opal/styles.css";

The CSS file defines the custom properties (--text-01, --background-neutral-00, etc.) that the Tailwind preset references.

2. Wire up the Tailwind preset

In your tailwind.config.js:

module.exports = {
  presets: [require("@onyx-ai/opal/tailwind-preset")],
  content: [
    "./src/**/*.{ts,tsx}",
    "./node_modules/@onyx-ai/opal/dist/**/*.{js,mjs}",
  ],
};

The content glob ensures Tailwind picks up the classes used inside Opal components.

You also need to define the underlying CSS variables (--text-01, etc.) in your own colors.css or import a copy from Onyx. The preset references them but does not define them — they live with the consumer so the consumer controls the palette.

Usage

import { Button, Text } from "@onyx-ai/opal/components";
import { Content } from "@onyx-ai/opal/layouts";
import SvgPlus from "@onyx-ai/opal/icons/plus";

function MyComponent() {
  return (
    <Content
      icon={SvgPlus}
      title="Hello"
      description="World"
      sizePreset="main-ui"
      variant="section"
    />
  );
}

Subpath imports

Subpath Contents
@onyx-ai/opal/components Buttons, Text, Tag, Tooltip, Popover, Table, etc.
@onyx-ai/opal/layouts Content, ContentAction, IllustrationContent, Section
@onyx-ai/opal/core Interactive primitives, Hoverable, Disabled
@onyx-ai/opal/icons SVG icon components
@onyx-ai/opal/illustrations Larger SVG illustrations
@onyx-ai/opal/types Shared types (RichStr, IconProps, etc.)
@onyx-ai/opal/utils cn, markdown helpers
@onyx-ai/opal/styles.css Bundled component CSS
@onyx-ai/opal/tailwind-preset Tailwind preset with tokens

Structure

web/lib/opal/
├── src/
│   ├── core/             # Low-level primitives (Interactive, Hoverable, Disabled)
│   ├── components/       # High-level components (Button, Popover, Tooltip, Table, ...)
│   ├── layouts/          # Layout primitives (Content, ContentAction, Section, ...)
│   ├── icons/            # SVG icon components
│   ├── illustrations/    # Larger SVG illustrations
│   ├── logos/            # Brand / product logos
│   ├── types.ts          # Shared types (RichStr, IconProps, etc.)
│   ├── utils.ts          # cn, markdown helpers
│   ├── shared.ts
│   └── root.css          # Library-owned design tokens
├── scripts/
│   └── bundle-css.mjs    # Concatenates root.css + leaf component CSS into dist/styles.css
├── package.json
├── tsconfig.json         # Source typecheck config
├── tsconfig.build.json   # Used by tsdown to emit dist/
├── tsdown.config.ts
├── tailwind-preset.cjs
└── README.md

Local development (inside the Onyx repo)

Opal reuses /web/node_modules — it does not have its own node_modules. To add a runtime dependency, declare it under peerDependencies in web/lib/opal/package.json AND add the matching version in the root web/package.json dependencies block, then run bun install in /web so Onyx's web app keeps building.

The package is consumed by web/ as a workspace via web/package.json's "@onyx-ai/opal": "./lib/opal". During Onyx development, web/ resolves Opal source through the @opal/* TypeScript path alias (defined in web/tsconfig.json), so changes are picked up live without running bun run build.

To produce the published artifact:

cd web/lib/opal
bun run build       # tsdown -> dist/, then bundle-css.mjs -> dist/styles.css

Releasing to npm

Releases go out through the Release Opal GitHub Actions workflow (.github/workflows/release-opal.yml). It uses npm OIDC Trusted Publishers — no NPM_TOKEN, signed provenance attestation. Pushing a tag is the only thing that triggers a release.

Steps:

  1. Bump version in web/lib/opal/package.json (semver: MAJOR.MINOR.PATCH, prerelease suffix -rc.N allowed).

  2. Open a PR with the version bump and any release-shaped changes. Merge it.

  3. From main, tag and push:

    git switch main && git pull
    git tag opal/v0.1.1
    git push origin opal/v0.1.1
    
  4. The workflow runs automatically on tag push. It builds (tsdown + CSS barrel) and runs bun publish --provenance --access public. Watch the run under the Actions tab; verify the new version on https://www.npmjs.com/package/@onyx-ai/opal.

The tag pattern must match opal/v*.*.* for the workflow to fire.

Conventions

  • Component directories are kebab-case (e.g. select-button/, open-button/, content-action/).
  • Each component dir contains components.tsx, README.md, styles.css (when needed), and a <PascalName>.stories.tsx (when applicable).
  • Imports inside the lib use the @opal/ path alias; never @/.
  • Types/interfaces are declared at the top of components.tsx without export; everything is re-exported from a single export { Foo, type FooProps }; block at the bottom.
  • See web/AGENTS.md for broader frontend standards.

Third-party trademarks

The @onyx-ai/opal/logos subpath ships brand marks of third-party products Onyx integrates with. Marks remain the property of their respective owners; Onyx claims no trademark over them. See NOTICE.md for details.