Skip to content

feat(app): show paced one-time tip toasts - #63664

Open
thdxr wants to merge 6 commits into
devfrom
tips-queue
Open

thdxr wants to merge 6 commits into
devfrom
tips-queue

Conversation

@thdxr

@thdxr thdxr commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Issue for this PR

requested by dax; no linked issue.

Type of change

  • New feature

What does this PR do?

tips are available in all desktop and web builds. after two minutes, a focused window can show one persistent tip. closing it or using its action saves the id on this device and starts a 24-hour wait. the first tip opens the chrome web store listing for browse; the second opens session search.

How did you verify your code works?

app and ui typechecks, queue and toast tests, and a chromium walkthrough of startup, dismissal and the next day’s tip.

Screenshots / recordings

toast and dismissed state (local review)

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

@opencodejr opencodejr Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks sound. I read through the toast and lock lifecycle and confirmed the server change works. Closing a tip or clicking its action records it as handled exactly once. Hiding the toast on blur or cleanup never counts as handled. With Web Locks, the lock is released when the tip goes away. The queue tests and the toast tests pass, and tsc is clean in app, ui, schema and server. GET /api/location returns experimental.tips_queue and honours OPENCODE_FLAGS. I couldn't drive the web app here because there's no browser, so the toast itself is checked only through your Chromium run.

Public API (all additions, backwards compatible):

  • GET /api/location gains an optional experimental: { tips_queue: boolean }.
  • The new config flag experimental.tips_queue is also controllable through OPENCODE_FLAGS.
  • In the OpenAPI spec, the response schema component is renamed from Location.PublicInfo to Location.PublicInfoEncoded. This happens because it is now a Schema.Class. The response shape doesn't change, but generators that reference the old component name will see the rename.
  • ToastOptions gains onDismiss.

Two small points are noted inline: the Install link doesn't match the description, and the tip flag is a fixed field on the location schema.

?.some((item) => item.name === "browse"),
action: {
label: "tips.browse.install",
run: () => platform.openExternal("https://chromewebstore.google.com/detail/mfnicocicmmlkpjnaffgihfjhdgjkdjg"),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description says the first tip links to https://opencode.ai/product/browse, but Install opens the Chrome Web Store listing directly. Is that intended? Also, the tip's when checks for an MCP server named browse. If installing the extension alone doesn't register that server, the tip will still be eligible after a user has installed browse. In practice it won't come back, because clicking Install already marks it as handled.

Comment thread packages/schema/src/location.ts Outdated
export interface PublicInfo extends Schema.Schema.Type<typeof PublicInfo> {}
export class PublicInfo extends Schema.Class<PublicInfo>("Location.PublicInfo")({
...Struct.omit(Info.fields, ["workspaceID"]),
experimental: Schema.optionalKey(Schema.Struct({ tips_queue: Schema.Boolean })),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This adds a single named flag to the public location response. Each future flag the app needs would then require its own schema and OpenAPI change. A generic record of the client-relevant flags, for example flags: Record<string, boolean> built from Flag.all, would avoid that and keep Location.PublicInfo a plain struct, without the component rename.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant