Commit Graph
245 Commits
Author SHA1 Message Date
zeekayandHanzo Dev be5c7e8e15 State a version once
A version written into a manifest is written into every manifest that wants it,
which is how eslint came to exist in a hundred and four forms across this estate
and how a package came to resolve twice at run time. The catalog moves the number
out of the manifest: a manifest names the package, the workspace names the
version.

Four are held below their latest because the newer release cannot be used, and
the reason is recorded rather than the version alone: @noble/hashes 2 renamed
every subpath the web3 stack imports, @splinetool/runtime 2 depends on a package
that was never published, @dynamic-labs 5.4.1 the same, and react-resizable-panels
3 points its types condition at the bundle.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 16:21:17 -07:00
zeekayandHanzo Dev 16e3157e98 One version per package, on the current release
Every dependency on a @hanzo/@luxfi/@zooai package now names the same version
across the repo: a catalog entry where pnpm supports one, an exact pin where it
does not, and a range only where a peer genuinely means one.

pnpm itself is pinned too — the estate ran eighteen different versions, five of
them too old to read a catalog.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 16:21:03 -07:00
zeekayandHanzo Dev 56faa8e370 Merge remote-tracking branch 'forge/main'
# Conflicts:
#	apps/bot-docs/package.json
#	apps/dev-docs/package.json
#	apps/docs/package.json
#	apps/flow/package.json
#	apps/platform/package.json
#	apps/team/package.json
#	apps/visor/package.json
#	examples/base-ui/package.json
#	examples/content-collections/package.json
#	examples/marble-cms/package.json
#	examples/next-min/package.json
#	examples/next/package.json
#	examples/obsidian/package.json
#	examples/openapi/package.json
#	examples/proposals/package.json
#	examples/python/package.json
#	packages/create-app/template/+next+hanzo-docs-mdx/package.json
#	pnpm-lock.yaml

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-29 13:38:17 -07:00
zeekay f50ba007b5 Merge remote-tracking branch 'origin/main'
Co-authored-by: Hanzo Dev <[email protected]>
2026-08-29 13:28:54 -07:00
zeekay f1df8db0dc fix(font): the lockfile agrees with the manifests again
Thirty-one manifests asked for @hanzo/font ^1.9.1 while the lockfile still
resolved 1.8.0, 1.8.2 and 1.8.12, so pnpm install --frozen-lockfile — which is
every workflow under .hanzo — refused to install anything at all.

The floor is 1.9.2 rather than 1.9.1 because 1.9.1's zen.css carries the
@font-face rules and nothing else: the :root block binding --font-zen-sans and
--font-zen-mono is absent, and a sheet reading either property gets an invalid
value and the OS default without saying so. 1.9.2 publishes them again.
2026-08-28 16:53:30 -07:00
zeekay 7218bcd39c fix(type): every app and every template a customer generates starts on Zen
Thirteen shipped apps and every scaffold in packages/create-app pulled their
face from Google at request time — Inter through next/font/google in the
examples and the four Next templates, Geist and Geist_Mono in the apps, and in
the seven react-router roots a bare <link> to fonts.googleapis.com. That last
one never even applied what it fetched: nothing in those trees set a family, so
the browser downloaded Inter, spent two preconnects on it, and rendered
system-ui. So `create-app` handed a customer a new docs site whose first act was
a third-party font request for a face that is not ours.

The apps read the family back through --font-sans and --font-mono, which are
next/font's handles rather than names of anything, so those follow the binding
over to --font-zen-sans and --font-zen-mono. Eight of them had only ever bound
the mono and were leaning on Tailwind's default for the text face; they now name
both, or swapping the binding would have dropped the body copy to system-ui
without a word.

Zen and ZenMono are built faces, not constructors — subsetting, display: swap
and fallback metrics are already in them — so the call and its options go away.
2026-08-28 11:30:07 -07:00
zeekay 05dbc79f05 fix(font): import the binding the package actually exports
Twelve example layouts imported `ZenSans` from `@hanzo/font/sans`, a name
the package stopped exporting at 1.9.0 — the family is called Zen, so the
binding is `Zen`. Every one of those layouts would fail to resolve the
import against a current install, and the `^1.8.x` ranges they pinned kept
resolving to the old export instead of surfacing it.
2026-08-28 08:37:06 -07:00
zeekay fd11bafcfa docs(examples): the templates people copy start on Zen, self-hosted
Twelve example apps opened with next/font/google Inter, so every developer who
copied one started their project on a face that is not ours and a request to a
font host we do not control. They use @hanzo/font's ZenSans (and ZenMono where
the example wanted a second family), with the dependency declared so it
resolves. examples/proposals bound --font-sans to var(--font-inter), a variable
nothing sets any more; it reads --font-zen-sans.
2026-08-25 11:00:52 -07:00
zeekay d7c6b30550 merge main into rebrand (branch is canonical: build-green + @hanzo/docs-*) 2026-06-24 23:25:47 -07:00
zeekay ada2f3d2ab rebrand: complete white-label — all packages @hanzo/docs-* (one brand)
Finish the fumadocs→Hanzo Docs rebrand: rename the remaining fuma-named
workspace packages and every reference so the framework is uniformly
@hanzo/docs-*. One brand, no Fuma in package names or product surface.

Package renames (name field + all refs: deps, imports, CSS @import,
configs, .changeset, next/vite build config):
  fumadocs-core        → @hanzo/docs-core
  fumadocs-mdx         → @hanzo/docs-mdx
  fumadocs-ui          → @hanzo/docs-ui          (packages/radix-ui)
  fumadocs-openapi     → @hanzo/docs-openapi
  fumadocs-preview     → @hanzo/docs-preview
  @fumadocs/base-ui    → @hanzo/docs-base-ui
  @fumadocs/basehub    → @hanzo/docs-basehub
  @fumadocs/language   → @hanzo/docs-language
  @fumadocs/local-md   → @hanzo/docs-local-md
  @fumadocs/sanity     → @hanzo/docs-sanity
  @fumadocs/shadcn     → @hanzo/docs-shadcn
  @fumadocs/vite       → @hanzo/docs-vite
  @fumari/stf          → @hanzo/docs-stf
  create-fumadocs-app  → @hanzo/create-docs
  create-fumadocs-versions → @hanzo/docs-create-versions

Stale @fumadocs/{cli,story,tailwind,mdx-remote,...} references collapsed to
their existing @hanzo/docs-* canonical packages (no dup created).

De-branded product strings: Fumadocs/Fuma prose → Hanzo Docs/Hanzo; site
branding, CLI output, doc copy, AI-assistant name, metadata. URLs
fumadocs.dev → docs.hanzo.ai, repo fuma-nama/fumadocs → hanzoai/docs.
Filesystem renames: packages/python/fumapy → hanzodocs_py, preview config,
what-is-fumadocs.mdx → what-is-hanzo-docs.mdx, api/fumadocs-ui route.

KEPT (real external npm deps / attribution — NOT renamed):
  fuma-cli, fuma-content, @fumari/json-schema-ts (published upstream pkgs),
  typesense-/trieve-fumadocs-adapter (3rd-party search adapters),
  LICENSE "Copyright (c) 2023 Fuma" (OSS attribution, all 7 LICENSE files
  untouched), CHANGELOG.md history (accurate release records, left as-is).

Build: node 24, pnpm install clean; all 4 target apps next build GREEN
(spec, gui-docs, zen-docs, base-docs) + full package closure (18/18 turbo).
Gate: zero @hanzo-package fumadocs-/@fumadocs/ references remain.
2026-06-24 23:21:42 -07:00
zeekay c49aa996fd fix(docs): normalize phantom names in CSS/astro/changeset/next-config (red review)
Follow-up to 903b1c38: the package-name normalization covered JS/TS imports +
package.json but missed four other surfaces that name the same phantom packages,
relocating the breakage from 'pnpm install' to 'next/vite/astro build':
- H1: 46 CSS @import strings (@hanzo/docs-{base-ui,ui,openapi}/css/*) → real pkgs
  (preserved legit @hanzo/docs-{twoslash,story} CSS)
- H2: examples/astro .astro imports (base-ui/mdx→fumadocs-ui/mdx, docs-core/toc→fumadocs-core/toc)
- L1: .changeset/config.json fixed-array lockstep names
- L2: removed apps/docs/next.config.mts dead phantom→phantom self-alias + dup keys
Found by adversarial red review of 903b1c38.
2026-06-24 15:52:22 -07:00
zeekay 868938c48b fix(docs): normalize phantom workspace package names — monorepo installs again
The fumadocs-fork rebrand left ~13 apps + examples referencing packages under
names that don't exist in the workspace (in BOTH directions: some kept
fumadocs-*, some became @hanzo/docs-*). pnpm install failed outright. Mapped
every reference (deps + imports, 607 source + 61 package.json) to the package
that actually exists, by suffix:
  @hanzo/docs-{core,mdx,ui,base-ui} → fumadocs-{core,mdx,ui} / @fumadocs/base-ui
  @fumadocs/{story,cli,mdx-remote,tailwind} → @hanzo/docs-{story,cli,...}
  fumadocs-{docgen,epub,twoslash,typescript} → @hanzo/docs-{...}
  drop phantom eslint-config-custom
Guarded @hanzo/docs-mdx vs -mdx-remote. Also fixes a pre-existing cli bug
(createConfigSchema referenced undefined isSrc) that blocked the package build.

Verified: pnpm install resolves clean (46.8s, was broken); package dist
regenerates phantom-free from the corrected source (hanzo-docs 430→0). Full
app build-green is blocked only by a node v26 toolchain bug in fumadocs-mdx's
config loader (repo targets node >=24.14; CI node builds it).
2026-06-24 15:17:27 -07:00
zooqueen 2f1c3172b6 refactor(api)!: rename toFumadocsSource() -> toDocsSource() (brand-neutral)
Renames the public doc-collection method across runtime, types, examples
and create-app templates so the API carries no upstream brand. The
internal helper and all call sites move together; fumadocs-core package
imports are untouched. Pairs with the .docs default outDir change.

BREAKING CHANGE: docs.toFumadocsSource() is now docs.toDocsSource().
2026-06-17 22:12:29 -07:00
zooqueen 079befb784 fix(mdx): default outDir to .docs and align all templates/examples
The plugin default outDir was 'docs' while every template and example
tsconfig aliased collections/* -> ./.source/*, so a fresh fork could not
resolve `import { docs } from 'collections/server'` without manually
passing createMDX({ outDir }). Standardize on .docs everywhere:

- packages/mdx/src/core.ts: _Defaults.outDir 'docs' -> '.docs'
- 31 template/example tsconfig: collections/* -> ./.docs/*
- align generated-dir .gitignore entries to .docs
- changeset (patch)
2026-06-17 22:12:29 -07:00
zeekay f3b95cca11 merge: upstream/main (preserve Hanzo brand, 334 commits)
# Conflicts:
#	apps/docs/app/(home)/sponsors/data.tsx
#	apps/docs/app/(home)/uwu.tsx
#	apps/docs/app/og/[...slug]/generate.tsx
#	apps/docs/app/static.json/route.ts
#	apps/docs/content/blog/customise-ui.mdx
#	apps/docs/content/blog/mdx-v10-summary.mdx
#	apps/docs/content/blog/openapi-v9.mdx
#	apps/docs/content/blog/v15.mdx
#	apps/docs/content/blog/v16-2.mdx
#	apps/docs/content/docs/(framework)/deploying/static.mdx
#	apps/docs/content/docs/(framework)/integrations/content/custom.mdx
#	apps/docs/content/docs/(framework)/integrations/openapi/generate-files.mdx
#	apps/docs/content/docs/(framework)/integrations/openapi/server.mdx
#	apps/docs/content/docs/(framework)/integrations/story/client.story.tsx
#	apps/docs/content/docs/(framework)/integrations/story/index.mdx
#	apps/docs/content/docs/(framework)/integrations/story/next.mdx
#	apps/docs/content/docs/(framework)/search/orama.mdx
#	apps/docs/content/docs/(framework)/what-is-fumadocs.mdx
#	apps/docs/content/docs/cli/index.mdx
#	apps/docs/content/docs/headless/mdx/headings.mdx
#	apps/docs/content/docs/headless/mdx/rehype-code.mdx
#	apps/docs/content/docs/headless/mdx/remark-image.mdx
#	apps/docs/content/docs/headless/source-api/plugins.mdx
#	apps/docs/content/docs/mdx/(integrations)/loader/node.mdx
#	apps/docs/content/docs/mdx/global.mdx
#	apps/docs/content/docs/mdx/index.mdx
#	apps/docs/content/docs/ui/components/banner.mdx
#	apps/docs/content/docs/ui/components/graph-view.mdx
#	apps/docs/content/docs/ui/layouts/flux.mdx
#	apps/docs/content/docs/ui/layouts/home-layout.mdx
#	apps/docs/content/docs/ui/layouts/root-provider.mdx
#	apps/docs/content/docs/ui/theme.mdx
#	apps/docs/eslint.config.mjs
#	apps/docs/scripts/preload.ts
#	apps/docs/scripts/update-orama-index.ts
#	examples/openapi/README.md
#	examples/openapi/scripts/generate-docs.ts
#	examples/react-router-i18n/scripts/preload.ts
#	examples/tanstack-start-story/src/components/callout/story-client.tsx
#	packages/base-ui/scripts/compile-inline.utils.ts
#	packages/cli/src/build/index.ts
#	packages/core/src/content/md/frontmatter.ts
#	packages/create-app/scripts/update-git-repo.js
#	packages/create-app/scripts/update-git-repo.sh
#	packages/mdx-runtime/eslint.config.mjs
#	packages/openapi/scripts/compile-inline.utils.ts
#	packages/openapi/src/server/create.ts
#	packages/openapi/src/ui/full.tsx
#	packages/openapi/src/utils/process-document.ts
#	packages/press/waku.config.ts
#	packages/radix-ui/scripts/compile-inline.utils.ts
2026-06-02 09:55:12 -07:00
6afbc8d1b4 feat(openapi): anchor links for request/response/parameter properties (#3327)
* feat(openapi): anchor links on schema properties

Each property rendered inline in a request body, response body, or parameter
now gets a stable id and a hover-revealed link icon, enabling deep links to
specific fields from guides. Ids follow:
  - body-<prop> for request bodies
  - response-<status>-<prop> for responses
  - parameters-<location>-<name> for parameters

A new idPrefix option on SchemaUI opts other Schema renderings into the same
behavior. See fuma-nama/fumadocs#3322.

* feat(openapi): deep-link nested schema properties

Extend the property anchor scheme to support hashes that point inside a
popover or below an array's "Show array" collapsible. Schema-internal
segments are joined with `.` so `#body.user.address.street` resolves
unambiguously regardless of dashes in property names.

On hash match, the inline anchor scrolls into view, the matching popover
auto-opens with its breadcrumb pre-navigated, the array collapsible
expands, and oneOf/anyOf tabs switch to the variant containing the
targeted field. The deep target is consumed after the first auto-open,
so subsequent user clicks on the same trigger get the base view; a
different deep hash re-arms it.

The hover anchor is now a copy-link button (matches fumadocs heading
anchors) that writes the full URL to the clipboard and updates the
address bar via history.replaceState (no hashchange, no popover reset).

* address PR review feedback

- Clarified the changeset: split anchor ID rules by context (request/response property paths vs flat parameter anchors) so dots aren't implied to apply to parameters.
- Namespaced anchors by media type when an operation has multiple request-body or response content types: prefix becomes `<media-slug>-body` / `response-<status>-<media-slug>`, and the content-type SelectTabs auto-switches to the targeted tab when a deep link arrives. Single-content-type operations keep the simple `body` / `response-<status>` form.
- Made findUnionPropMatch validate the *full* remaining path (via new pathResolves helper) so two variants that share the first prop name no longer race; the wrong tab can't be selected for a deep hash anymore.
- Reset SchemaUIPopover breadcrumb state when initialPath changes so a fresh deep hash takes effect on an already-open popover.
- Replaced the lossy slugifyPropertyName with encodeURIComponent (plus % encoding for `.`) so property anchors stay collision-safe across case-only differences, punctuation-only differences, and non-ASCII keys, while `.` remains exclusively a path separator.

* address PR review feedback

- Fix potential hydration mismatch in useTabValueFromHash by initializing state with the fallback value and resolving from the URL hash inside useEffect; the deep-linked tab now corrects after hydration on the client.

* fix(openapi): move useTabValueFromHash into a client component

The previous hydration-mismatch fix put `useEffect`/`useState` directly in
`operation/index.tsx`, which is a Server Component — Next refused to compile
because RSC modules can't import client-only React APIs. Extract the
hash-aware tab wrapper into `operation/hash-tabs.tsx` (with `"use client"`)
and switch both body and response sites to `HashAwareSelectTabs`. The parent
tree stays server-side; only the tab wrapper hydrates on the client.

* address PR review feedback

- Wrap decodeURIComponent in try/catch in both deep-link hash parsers so a malformed percent-encoded fragment (e.g. `#body%`) is treated as "no target" instead of throwing URIError and breaking tab / popover resolution.

* address PR review feedback

- Match the URL hash against DOM ids using the raw fragment first, with the fully-decoded form as a fallback, in both DeepLinkProvider and hash-tabs. Property anchors are generated via slugifyPropertyName (which percent-encodes reserved chars like `.`), so DOM ids contain the encoded form; decoding the hash before lookup caused links like `#body.foo%2Ebar` to miss the matching element.

* redesign

* fix types

---------

Co-authored-by: Fuma Nama <[email protected]>
2026-06-02 03:43:01 +08:00
Fuma Nama 322cc35208 chore: bump deps 2026-05-26 19:49:18 +08:00
Fuma Nama 1cf69279c8 OpenAPI: Add Source API methods & Dynamic Source support to server 2026-05-18 19:42:18 +08:00
39f9a505a0 OpenAPI: render deprecated badge for deprecated operations (#3281)
* OpenAPI: render deprecated badge for deprecated operations

Show a yellow "Deprecated" badge for any OpenAPI operation marked
`deprecated: true`. The badge appears in two places: inline with the
operation heading when `showTitle` is true, and as a standalone header
above the playground card when `showTitle` is false (which is the
default for individual operation pages generated by `openapiSource`).

This restores the behaviour originally added in #2417, which was lost
during the v9→v10 move of the operation renderer from
`packages/openapi/src/render/operation/index.tsx` to
`packages/openapi/src/ui/operation/index.tsx`. The parameter-level,
schema-property-level and auth-scheme-level deprecated badges all
survived the refactor; the operation-level one was silently dropped.

The example spec's `deletePlanet` operation already claimed in its
description to be deprecated but never set the flag (inherited from the
upstream Scalar Galaxy fixture). Setting it both fixes the
inconsistency and provides a visible demo for the new badge.

* OpenAPI: improve operation deprecation styles

---------

Co-authored-by: Fuma Nama <[email protected]>
2026-05-14 17:18:41 +08:00
Fuma Nama 44480d1117 Refactor: pnpm v11 & remove bun 2026-05-12 18:50:36 +08:00
Fuma Nama 6fc62b7ec9 Press: fix HMR 2026-05-09 21:30:38 +08:00
Fuma Nama a02b746fc2 MDX: Make source config optional in Vite plugin 2026-05-08 16:28:55 +08:00
Fuma Nama 73c9f7cee7 Bump deps 2026-05-07 22:40:49 +08:00
Fuma Nama 4e112dcd00 Sanity: ship content types via regsitry 2026-05-02 21:43:17 +08:00
Fuma Nama 0f30271811 Chore: bump deps 2026-04-27 23:21:15 +08:00
Fuma Nama b8adbddd86 Bump deps 2026-04-24 20:07:29 +08:00
Fuma Nama 75fe4cd4ea Bump deps 2026-04-19 22:23:53 +08:00
Fuma Nama 6d51a6c60c Docs: update for 16.8 2026-04-19 22:15:40 +08:00
Fuma Nama dd7eaa21ab Chore: bundle more deps 2026-04-12 13:41:16 +08:00
Fuma Nama 7081779a25 CLI: Clean unused files 2026-04-08 15:15:57 +08:00
Fuma Nama c4b2e30a5d Twoslash: Force default options for TypeScript 6 2026-04-01 20:33:49 +08:00
Fuma Nama e67d16f2ca Templates: improve scrollbar-gutter & react-remove-scroll 2026-04-01 19:41:39 +08:00
Fuma Nama 9359ca71b4 Chore: set scrollbar-gutter by default 2026-03-26 22:26:00 +08:00
Fuma Namaandzeekay 8bb84ceea1 Chore: migrate TypeScript 6 & Lucide 2026-03-24 19:01:44 -07:00
Fuma Nama 5a42a39eb1 Chore: migrate TypeScript 6 & Lucide 2026-03-24 23:59:05 +08:00
zeekay a9be7fc34e docs: referral program service page — tiers, API, OSS fund, fraud prevention 2026-03-22 19:10:16 -07:00
zeekay 968d566467 feat: merge upstream fumadocs 16.6+ (182 commits) and rename to @hanzo/docs-*
Upstream changes include:
- UI: improved TOC detection, clerk variant, slot support
- Base UI: redesigned home layout navigation menu
- CLI: slot support in customise command
- OpenAPI: unsetting auth fields in playground
- Multiple version package releases

All fumadocs-* imports renamed to @hanzo/docs-* namespace.
2026-03-22 18:43:20 -07:00
Fuma Nama d844615993 UI: fix TOC 2026-03-21 22:48:56 +08:00
Fuma Nama 29f7c859c8 Chore: Bump deps 2026-03-19 23:40:55 +08:00
zeekay a166e80677 Merge upstream fumadocs dev (16.6.17) with @hanzo/docs namespace rename
Merge 131 upstream commits from fuma-nama/fumadocs dev branch, bringing
framework packages to v16.6.17. All fumadocs-* and @fumadocs/* package
references renamed to @hanzo/docs-* namespace.

Upstream additions:
- packages/content/ (@hanzo/docs-content) - Fuma Content adapter
- packages/epub/ (@hanzo/docs-epub) - EPUB export support
- MarkdownCopyButton, ViewOptionsPopover in docs page layout
- Flexsearch, Orama search integration
- Shiki v4 upgrade
- Various UI framework improvements

Hanzo customizations preserved:
- apps/docs/content/ (all Hanzo service/project docs)
- apps/docs/app/ (Hanzo homepage, AI chat, subdomain routing)
- apps/docs/components/ (AI search, error boundaries, auth)
- apps/docs/lib/ (source config, OpenAPI, metadata)
- Webpack alias layer for upstream project doc imports
- MdxErrorBoundary wrapper for graceful MDX failures
2026-03-16 14:34:53 -07:00
Fuma Nama efd7bc5912 Chore: Migrate to Vite 8 2026-03-13 18:11:02 +08:00
Fuma Nama 559864566c UI: fix broken tsdown CSS logic 2026-03-11 17:07:54 +08:00
Fuma Nama ea74cb403b Chore: enforce type-safe MDX components universally 2026-03-10 19:59:51 +08:00
Fuma Nama 9eaa1fc7ef Docs: rename fumadocs-mdx:collections/ to collections/ universally 2026-03-10 17:28:26 +08:00
Fuma Nama 79a19da430 Bump deps 2026-03-05 23:27:10 +08:00
Fuma Nama d0fdb258e7 Chore: use Shiki.js v4 2026-03-01 19:57:41 +08:00
Fuma Nama 2075c29944 Chore: bump deps 2026-02-26 20:48:28 +08:00
zeekay ef5b0b4f85 merge upstream fumadocs dev (66 commits up to 16.6.5) with Hanzo branding
Merges upstream commits a57b2646..159300157 from fuma-nama/fumadocs dev branch,
including:

- Core/UI/Base-UI version bump 16.5.3 -> 16.6.5
- OpenAPI version bump 10.3.4 -> 10.3.9 (3.2 support, server selector)
- TypeScript version bump 5.1.3 -> 5.1.4 (tag parser, type table ID)
- Markdown search improvements (inline elements, codeblocks, Vietnamese)
- CSS performance improvements and accessibility fixes
- MDX stringification using mdast-util-to-markdown
- Sidebar active link items support
- Mixedbread search moved to server-side
- Tailwind CSS plugin forwarding for module resolution
- Cursor integration replacing T3 Chat in templates
- Template cleanup (removed deprecated mdx-remote example)

All fumadocs-* packages renamed to @hanzo/docs-* namespace.
Removed duplicate +next+fuma-docs-mdx templates (using hanzo-docs-mdx).
Upstream metadata (homepage, repository) updated to Hanzo.
2026-02-23 13:04:49 -08:00
Fuma Nama 7a41536c0b OpenAPI: refactor to support OpenAPI 3.2 2026-02-17 21:17:17 +08:00
Fuma Nama dd3c0afc72 Base UI: fix search dialog shortcuts 2026-02-13 19:03:36 +08:00