67 Commits

Author SHA1 Message Date
拉罐 f01ca6579d fix(ci): scope CN build region and isolate OSS uploads (#1236)
让 CN 构建的区域变量覆盖完整构建链,确保导航按 CN 规则生成。
移除 CN 产物写入全局 OSS 路径的命令,避免跨区域资源覆盖。

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-01 19:03:41 +08:00
twosugar 43a386ca92 chore(lint): 引入 oxlint 并清理未使用代码
新增 oxlint@1.80.0 + .oxlintrc.json + lint/lint:fix 脚本;清空所有
no-unused-vars 告警(未用 React/导入/变量/参数),删除无引用的 ui/Skill。
oxlint exit 0。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-28 16:14:18 +08:00
twosugar 23d933de76 feat(migrate): docs content font → self-hosted Inter (match legacy .vp-doc)
Boss noticed the article font differed. Legacy self-hosts Inter (woff2) and
renders `.vp-doc` content in Inter 15px / ~1.75 line-height — a different
face from the SF Pro Display used by the site chrome (nav/marketing). Our
Astro build used SF Pro Display for everything, so the doc body was the
wrong typeface + size (16px).

- Added `@fontsource-variable/inter` (self-hosted variable font, same
  approach as legacy — no external Google Fonts request).
- Imported it in global.css.
- `.docs-content` now uses `"Inter Variable", Inter, ui-sans-serif,
  system-ui, …` at 15px / 1.75 line-height (headings inherit Inter; code and
  tables keep their mono / 14px). Site chrome keeps SF Pro Display.

Verified: Inter Variable loads (document.fonts.check true); .docs-content p
= Inter 15px, h1 = Inter 32px; nav still SF Pro Display.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-24 18:57:07 +08:00
twosugar 0ab585eece feat(migrate): real search — build-time JSON index + minisearch + legacy UI
Boss test: dev environment showed "Search is available after first
production build" — pagefind only generates its index during
`bun run build`, which was flagged as a broken user experience.

Swap the whole search substrate to build-time JSON index +
client-side minisearch:

- **`src/pages/search-index.[locale].json.ts`** (new) — Astro dynamic
  route emitting `/search-index.{en,zh-CN,zh-HK}.json`. Each doc is
  sliced into sections (one per heading), each carrying the ancestor
  heading breadcrumb (h1 → h2 → h3) so the client can render the
  legacy `# Board - Security Board` / `# Scene Demonstration >
  Submit Order` layout without a second round-trip. Body text is
  stripped of MDX / code fences / markdown syntax and capped at 2000
  chars per section. Runs during both `astro dev` and `astro build`
  — dev serves it live, so the search works from the first click.
  Region-filtered via `includedInRegion` so CN builds get the CN
  sitemap.

- **`SearchDialog.tsx`** — pagefind removed; minisearch@7 added.
  Per-locale index cached in a module-level `Map` so subsequent opens
  are instant; first open pays one fetch + `addAll`. Custom
  `tokenize` splits CJK into per-character tokens while keeping
  western words whole — needed because minisearch's default whitespace
  tokenizer produces zero tokens for `实时行情报价`. Fields boosted
  `title:3, headings:2, body:1`, `prefix + fuzzy 0.15`. Debounce
  effect re-fires on `status` change so a query typed while the
  index is still loading gets served the moment it's ready. Dialog
  chrome updated to match legacy image #25 — search icon, clear
  button, keyboard hint bar (↑↓ Switch · ↵ Select · esc Close), and
  the same `--app-mono` kbd styling as the ⌘K badge.

- **`SearchResults.tsx`** — new UI:
    #  <h1 title> > <h2 title> > <h3 title>
  with matched query terms wrapped in a teal `<mark>` (against
  `--lb-fg-invert`), and the deepest heading rendered bold. Selected
  row gets a teal border + inset ring — same active-state affordance
  as the legacy screenshot.

- **De-dup guard** — the section builder occasionally emits two
  sections with identical `id` when a doc reuses a heading text at
  the same depth (e.g. two `## Examples` blocks); MiniSearch throws
  on duplicate adds. Filtered client-side before `addAll`.

- **extractField gotcha** — MiniSearch v7's `extractField` is used
  for BOTH tokenization AND `storeFields`. Naively stringifying every
  field turns the `headings: string[]` array into "a,b,c" in the
  stored result, and the UI's `hit.headings.map(...)` crashed with
  "map is not a function" — the dialog disappeared to a blank
  fallback. Fixed by returning raw values for non-virtual fields and
  only stringifying the synthetic `headingsJoined` for tokenization.

Verified in Chrome DevTools: dev-served /search-index.en.json returns
2698 sections (1.1 MB), first-open build takes ~800 ms, typing
"security" returns 12 hits including "# Security News",
"# longbridge security-list › Examples", "# longbridge security-list
› Examples › List securities by market" — exactly the legacy shape.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-19 15:45:59 +08:00
twosugar 3679945744 feat(migrate): port inspira animation components to React workspace
Sprint 2 §S9. Ports 18 vue animation components (1462 lines) from
`docs/.vitepress/theme/components/inspira/` to React inside a new
`packages/inspira` workspace published as `@longbridge/openapi-inspira`.
Adds `motion` (v13.x — API-compatible with the ^11 the plan
suggested; `motion-v` in vue → `motion/react` in React).

Files created (18 components + barrel):
- packages/inspira/package.json — bun workspace, motion dep
- packages/inspira/tsconfig.json
- packages/inspira/src/index.ts — barrel
- packages/inspira/src/AnimatedBeam.tsx (from 190-line vue)
- packages/inspira/src/BentoGrid.tsx (18)
- packages/inspira/src/BentoGridItem.tsx (32)
- packages/inspira/src/BlurReveal.tsx (54)
- packages/inspira/src/BorderBeam.tsx (61)
- packages/inspira/src/BoxReveal.tsx (47)
- packages/inspira/src/ColourfulText.tsx (73)
- packages/inspira/src/FlickeringGrid.tsx (256)
- packages/inspira/src/GlowBorder.tsx (59)
- packages/inspira/src/GlowingEffect.tsx (94)
- packages/inspira/src/InteractiveGridPattern.tsx (70)
- packages/inspira/src/InteractiveHoverButton.tsx (64)
- packages/inspira/src/Marquee.tsx (73)
- packages/inspira/src/Meteors.tsx (57)
- packages/inspira/src/MorphingText.tsx (100)
- packages/inspira/src/NumberTicker.tsx (75)
- packages/inspira/src/ShimmerButton.tsx (75)
- packages/inspira/src/TextHighlight.tsx (64)

Migration decisions:
- `motion/react` in place of `motion-v` — same underlying framer-motion
- CSS keyframes from Vue `<style scoped>` re-emitted as `<style>` JSX
  tags with `inspira-` prefix to prevent collisions
- `propsRef` pattern in FlickeringGrid + MorphingText to avoid stale
  closures in RAF loops
- `useElementVisibility` + `useTransition` (@vueuse/core) replaced with
  native `IntersectionObserver` + `requestAnimationFrame`
- Fixed 2 type errors uncovered by check: duplicate borderRadius in
  GlowBorder inline styles; canvas/ctx narrowing through nested
  closures in FlickeringGrid

Modified:
- root package.json — @longbridge/openapi-inspira workspace dep +
  motion dep

Verified:
- astro check: 0 errors (132 files)
- 8 canonical URLs return 200

Deferred: rewiring homepage sections to use inspira components lands
alongside §S10 composite polish; §S9 scope is producing the package.

Closes Sprint 2 §S9.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-19 10:12:38 +08:00
twosugar d83d52b73d feat(migrate): port TryIt (interactive API caller) to React workspace
Sprint 2 §S7. Ports legacy TryIt (9 vue files under
`docs/.vitepress/theme/components/TryIt/` + `theme/utils/{http-client,
websocket-client}.ts`) to React inside a new `packages/tryit` workspace
published as `@longbridge/openapi-tryit`. Uses react-hook-form for
form generation from openapi schema; fires real API requests against
`openapi.longportapp.com`.

Files created:
- packages/tryit/package.json — bun workspace, deps: react-hook-form,
  @longbridge/openapi-utils, @longbridge/openapi-api-reference
- packages/tryit/tsconfig.json
- packages/tryit/src/index.ts — barrel
- packages/tryit/src/TryIt.tsx — orchestrator: button mode → panel mode,
  data-lbus-component="tryit" preserved
- packages/tryit/src/AuthorizationForm.tsx — cookie/localStorage-backed
  appKey / appSecret / accessToken inputs
- packages/tryit/src/ParametersForm.tsx — walks op parameters + request
  body via SchemaRenderer
- packages/tryit/src/PlayButton.tsx — assembles request, dispatches via
  clients
- packages/tryit/src/ResponseView.tsx — pretty-prints JSON response
- packages/tryit/src/tryit.css — form + response viewer styles
- packages/tryit/src/clients/http-client.ts — verbatim port of legacy
- packages/tryit/src/clients/websocket-client.ts — verbatim port of legacy
- packages/tryit/src/utils/app-id.ts — id derivation
- packages/tryit/src/utils/request.ts — request assembly helper
- packages/tryit/src/hooks/useTryItMode.ts — `?mode=try-it` URL toggle
- packages/tryit/src/hooks/useAuthorization.ts — cookie sync
- packages/tryit/src/hooks/useResponse.ts — response state

Modified:
- src/mdx-components.tsx — swap import from placeholder to
  `@longbridge/openapi-tryit`
- root package.json — workspace dep

Deleted:
- src/components/mdx/placeholders/TryIt.tsx

Verified:
- astro check: 0 errors (0 new warnings)
- All 15 canonical URLs return 200
- `<TryIt />` registered in mdx-components; mount site (frontmatter
  `httpInfo` or explicit tag) is handled by later plumbing

Closes Sprint 2 §S7.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-19 01:26:53 +08:00
twosugar 535dc86a7a feat(migrate): port ApiReference (Scalar-style) to React workspace package
Sprint 2 §S6. Ports legacy `docs/.vitepress/theme/components/ApiReference.vue`
(1370 lines) to React inside a new `packages/api-reference` workspace
published as `@longbridge/openapi-api-reference`. Zero use of
`@scalar/*` or any third-party OpenAPI viewer — this is a manual 1:1 port.

Match legacy behaviour:
- Hash routing via `?op=<epId>` and `?page=<pageId>` + popstate listener
- Three views: intro / page / endpoint
- Sidebar with search + tag groups + method-color badges (GET/POST/PUT/DELETE)
- markdown-it prose rendering + external-link renderer patch
- Schema tree walker with `$ref` resolution + envelope detection
- Code-sample tabs (JS/Python/Rust/Java/Go/C++) via inline regex highlighter
- `QuotePermission` badge sourced from `quote-permissions.yaml`
- Locale-aware doc-link rewrites (`localizeDocLinks`)
- Dark mode double-guard `[data-theme="dark"]` + `prefers-color-scheme`

Files created:
- `packages/api-reference/package.json` — bun workspace, deps js-yaml + markdown-it
- `packages/api-reference/tsconfig.json` — extends root, includes .astro types
- `packages/api-reference/src/index.ts` — barrel
- `packages/api-reference/src/openapi-loader.ts` — yaml.load + $ref resolver
- `packages/api-reference/src/ApiReference.tsx` — top-level CSR component
- `packages/api-reference/src/CodeSample.tsx` — code panel + syntax highlight
- `packages/api-reference/src/QuotePermission.tsx` — permissions badge
- `packages/api-reference/src/api-reference.css` — 280px sidebar + fluid main +
  440px code panel + method colors + dark-mode

Files modified:
- `src/layouts/ApiReferenceLayout.astro` — mounts <ApiReference client:load
  rawYaml={rawYaml} locale={locale} /> with the CSS import (needed subpath in
  the package's `exports` field to resolve the CSS through the workspace name)
- `src/data/locale.{en,zh-CN,zh-HK}.ts` — api.* keys (search, section labels,
  copy states, intro copy, param labels, fallback, pathCopy)
- `src/mdx-components.tsx` — remove dead ApiReference entry (mounted via
  layout, not mdx tag)
- root `package.json` — workspace dep `@longbridge/openapi-api-reference`

Files deleted:
- `src/components/mdx/placeholders/ApiReference.tsx`

Runtime bugfix (post-subagent): package.json `exports` field only exposed
`.` and rejected `./src/api-reference.css` subpath, throwing a 500 on every
route once the layout tried to import the CSS. Added the CSS subpath to
`exports`. All 15 canonical URLs return 200 after fix.

Verified:
- astro check: 0 errors (85 files)
- /docs/api renders with sidebar (Overview / Real-Time Market Data / Error
  Codes + tag groups Watchlist Management / Market Temperature / Portfolio
  & Cash / News & Filings + method-color badges) + intro cards
  (REST API / WebSocket) — screenshot in gate/s6-verify-api.png
- /zh-CN/docs/api, /zh-HK/docs/api, /docs/quote/overview all 200
- `data-lbus-component` on api-reference / api-sidebar / api-intro

Closes Sprint 2 §S6 (gate finding A13 / A14).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-19 01:00:50 +08:00
twosugar 0e2dcb4c81 refactor(migrate): extract @longbridge/openapi-utils workspace package
Sprint 2 §S5: move src/lib/{slug,region,navigation,i18n}.ts + tests
into a new bun workspace `packages/utils` published as
`@longbridge/openapi-utils`. Consumers import from the package name
instead of relative paths or `@lib/*` aliases.

Files moved (git mv preserves history):
- src/lib/slug{,.test}.ts       → packages/utils/src/
- src/lib/region{,.test}.ts     → packages/utils/src/
- src/lib/navigation{,.test}.ts → packages/utils/src/
- src/lib/i18n.ts               → packages/utils/src/

New package skeleton:
- packages/utils/package.json (private workspace, "@longbridge/openapi-utils")
- packages/utils/tsconfig.json (extends root, includes .astro types
  so `astro:content` resolves in isolated TS server)
- packages/utils/src/index.ts (barrel re-exports)

Consumer updates (22 files): shell components, layouts, [...slug]
routes on all 3 locales, llms.txt endpoints, md endpoint — all import
from `@longbridge/openapi-utils` now.

tsconfig.json — removed `@lib/*` alias (dead after the move); other
aliases (`@/*`, `@components/*`, `@styles/*`, `@data/*`) intact.

Two slug.test.ts expectations updated to reflect the T3 semantics
locked in during Sprint 1.5:
- absolute slug in `en/docs/**` → `/docs/{slug}` (was `/{slug}`)
- absolute slug in `zh-CN/docs/**` → `/zh-CN/docs/{slug}` (was `/zh-CN/{slug}`)
- new coverage: absolute slug for `en/{marketing}.mdx` still site-absolute
The test file was carrying pre-T3 expectations; §S5 is when
they had to move regardless, so the correction lands here.

Verified:
- astro check: 0 errors (81 files)
- vitest: 23/23 pass
- 8 canonical URLs: all 200
- zero residual `../lib/*` / `@lib/*` import paths anywhere in
  src/ or packages/

Known deferred:
- `packages/utils/src/i18n.ts` still reads locale data via
  `../../../src/data/locale.*` (cross-boundary). Acceptable for §S5
  scope; §S10 may relocate locale data into the utils package.

Closes Sprint 2 §S5.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-18 22:13:43 +08:00
twosugar ae2121ff50 feat(migrate): render vitepress ::: callouts and Tabs UI
Sprint 1.5 mini §S11 gate flagged (A8, A12, A20):
- vitepress `:::warning`/`:::tip`/`:::success` containers render as raw
  text ("`:::warning Package Renamed`" appears in body) — 335 usages
- `<Tabs><TabItem>` ships to browser but tab bar never appears; all
  TabItems stack under each other (e.g. macOS/Windows/Linux install
  commands, /sdk language SDK panels)

A8 — Callout directive rendering
--------------------------------

remark-directive v4 (micromark-extension-directive) rejects the bare
title form `:::warning Package Renamed` and only accepts bracket labels.
Two-part fix:

- Preflight Rule 10 rewrites `:::name Title` → `:::name[Title]` in mdx
  source before the remark pipeline; scoped to known names
  (success/warning/tip/info/danger/note/caution) and never rewrites
  lines that already use `[…]` or `{…}` syntax.
- New remark plugin `src/integrations/remark-callout.ts` transforms
  parsed `containerDirective` AST nodes into
  `<div class="callout callout-{name}" role="note"
    data-lbus-component="callout-{name}">` with an optional
  `<p class="callout-title">` from the directive label (default:
  capitalised name).
- `src/styles/callout.css` maps each variant to `--lb-status-*` /
  `--lb-brand` tokens: warning=orange, danger=red, tip=teal,
  success=green, info/note/caution=blue.

A12/A20 — Tabs SSR + client hydration
--------------------------------------

Root cause: Astro renders each React component in mdx in its own React
root — `<Tabs>` children arrive as pre-serialised HTML, so
`React.Children.forEach` yields nothing, and `<TabItem>` never sees
`TabsContext.Provider`. The `useState`+`useEffect`+`registerTab` pattern
was silently no-op'ing.

Rebuilt as progressive-enhancement:

- `packages/ui/src/TabItem.tsx` — `!ctx` branch emits
  `data-tab-value`/`-label`/`-default` attrs for a client script to
  discover. TabItem's public props unchanged.
- `packages/ui/src/Tabs.tsx` — removes broken `useMemo` introspection;
  SSR renders `<div data-lbus-component="tabs" data-tabs-group-id=…
  data-tabs-variant=…>` with an empty `<div data-tabs-bar>` placeholder
  and children below. `registerTab`/localStorage machinery retained
  for future client:load hydration paths.
- `src/scripts/tabs-hydrate.ts` — vanilla-JS module bundled by Vite.
  On `DOMContentLoaded` walks `[data-lbus-component="tabs"]` wrappers,
  reads TabItem attrs, builds `<button>`s into the empty bar, hides
  non-active TabItems via inline style, wires click handlers, honours
  the existing localStorage `vitepress-tabs-{groupId}` key + syncs
  cross-instance via `__LBTabsState` / `__LBTabsListeners`.
- `src/layouts/BaseLayout.astro` — appends
  `<script>import '../scripts/tabs-hydrate'</script>` before `</body>`.

The vanilla-JS path deliberately mirrors the pre-existing React
`__LBTabsState` API so future migrations back to a React-hydrated Tabs
(e.g. under `client:load`) can coexist without behavioural diff.

Verified:
- astro-check green (after adding `export {}` to tabs-hydrate.ts so
  `declare global` is legal in a module context)
- 8 canonical URLs return 200
- chrome-devtools MCP 1440×900 hard-reload:
  - /docs/cli/install shows 4 tabs (macOS Homebrew / Linux macOS
    Script / Windows Scoop / Windows PowerShell), only active tab's
    code visible
  - /sdk shows orange "Package Renamed" callout with border-left +
    tinted background; 6 language tabs (Python / JavaScript / Rust /
    Java / Go / C++) render, only active tab visible

Closes Sprint 1.5 T5. Sprint 1.5 remediation complete — next: re-run
mini §S11 gate before beginning Sprint 2.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-18 17:53:36 +08:00
twosugar 56332715f4 feat(migrate): restore heading anchor ids for direct-link parity
Stage-1 preflight stripped `## Foo {#bar}` syntax to unblock MDX parsing,
leaving all `#anchor` deep-links broken across the site (spec §-1 URL
parity requirement).

Two-path anchor pipeline:

1. Plain headings (`## Foo`): rehype-slug auto-generates slugified id,
   rehype-autolink-headings appends `.header-anchor` link.

2. Explicit-id headings (`## Foo {#bar}`): preflight Rule 2 no longer
   strips — it now converts to JSX `<h2 id="bar">Foo<a …/></h2>` BEFORE
   MDX/acorn parses the `{#bar}` expression. Preserves explicit ids
   which matter for zh-CN/zh-HK where heading text ≠ id
   (e.g. `## 频率限制 {#rate-limit}`).

Both paths emit equivalent HTML: `<h{n} id="…">…<a class="header-anchor"
aria-hidden="true" tabindex="-1"></a></h{n}>`.

CSS for `.header-anchor` appended to tokens.css (uses `--lb-fg-2` muted
token; `--lbus-c-text-muted` was proposed in plan but does not exist).

Verified:
- astro-check green
- dev-side: en `id="rate-limit"`, zh-CN `id="接口类型"` + `id="rate-limit"`,
  zh-HK equivalent
- 884/884 URLs return 200

Deviation from S3 plan: Rule 2 kept and rewritten rather than removed.
Root cause of plan text drift: acorn parses JSX expressions before
remark plugins run, so remark-heading-id cannot intercept `{#bar}` in
mdx source — the smart-conversion approach is the correct fix.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-18 12:22:14 +08:00
twosugar 7d8f5ff49f fix(migrate): stage-1 dev URL 100% coverage — mdx preflight + collection + shell CSS
Boss verified the stage-1 spec/plan closure only checked astro-check + unit
contracts; no reviewer ever started dev. First `bun run dev` revealed that
the entire shell was unstyled and 884 content routes had 0/500/404 rates
scattered across mdx edge cases. This is the full recovery pass.

- content.config.ts: Astro 5+ glob loader was using frontmatter `slug:` as
  entry.id, deduping ~410 tri-locale entries and breaking resolveUrl. Force
  generateId to derive from file path. Introduce `docs_layout` schema
  field for the renamed frontmatter.
- 3× [...slug].astro: dispatch on `docs_layout` (renamed by preflight).
- SearchDialog.tsx: hoist `/pagefind/pagefind.js` URL into a runtime var
  and HEAD-probe before dynamic import so Vite's static analyzer doesn't
  fail the whole page when the pagefind bundle isn't built yet.
- global.css: add explicit @source directives so Tailwind v4 scans src/,
  packages/ui/, and docs/ for utility classes.
- shell.css (new, ~330 lines): stopgap CSS for the semantic BEM classNames
  the shell/mdx composite subagents shipped without CSS. Stage-2 will
  codemod each into Tailwind utilities colocated on components (spec §T3).
- astro.config.ts: 7-rule `lbus-mdx-preflight` vite transform for vitepress
  legacy syntax that mdx can't parse:
  1. `layout:` → `docs_layout:` frontmatter (avoid astro-mdx module resolve
     on values like "api-reference").
  2. Strip `## Foo {#bar}` heading anchors.
  3. Strip `<style scoped>...</style>` blocks.
  4. Convert `<https://...>` autolinks to plain URLs.
  5. Escape placeholder tags like `<id>`, `<token>` (HTML whitelist incl.
     `<center>` preserved).
  6. Strip leading `:` from vue-style JSX props (`:title=` → `title=`).
  7. Strip `<!-- HTML comments -->`.

Also switched `remarkPlugins` from `mdx({...})` (deprecated in Astro 7) to
`markdown.remarkPlugins` and installed remark-heading-id (currently unused
since preflight strips anchor syntax; stage-2 will restore anchors via
rehype-slug or fix the plugin integration).

Verified: 884/884 dev URLs return 200. Astro check 0 errors.

Stage-2 blockers not addressed by this commit (see ledger):
- `bun run build:canary` still fails on screener_search.mdx:203 Go struct
  literal inside a fenced code block (Astro 7 rolldown+oxc bug).
- Heading anchor ids are stripped; navigation to #hash fragments won't
  scroll to the right place.
- BEM classNames should be codemodded to Tailwind utility classes.
- `<style scoped>` content is discarded; page-scoped CSS not migrated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-18 10:18:17 +08:00
twosugar 2b9e58697e chore(migrate): purge vitepress residuals and archive legacy reference
Stage-1 closure commit. The vitepress reference archive in .legacy/ has
served its purpose as a port reference through T2–T17 and is now removed.

Removed from package.json (not consumed by any src/scripts/packages code):
deps: @headlessui/vue, @jsonforms/core, @jsonforms/vue, @jsonforms/vue-vanilla,
      @vue-flow/background, @vue-flow/core, @vueuse/core, floating-vue,
      markdown-it, motion-v, reka-ui, shiki, vue-i18n
devDeps: @unocss/extractor-mdc, @unocss/transformer-variant-group,
         markdown-it-container, markdown-it-mathjax3, sass-embedded,
         unocss, vitepress, vitepress-plugin-group-icons,
         vitepress-plugin-mermaid, vue

Not present in package.json (skipped cleanly): @vitejs/plugin-vue,
@vue/tsconfig, vue-tsc.

Added to .gitignore: dist-diff/, .baseline-dist/, .baseline-sitemap.xml
(opencli artifact dirs for boss's manual verification pass).

astro check: 0 errors. .vue files in src tree: 0. bun install: 23 packages
removed.

Boss's next step: run opencli url-diff / dom-diff / visual-diff against
vitepress baseline to confirm stage-1 URL parity.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 20:03:28 +08:00
twosugar 53666718af feat(migrate): opencli — url/dom/visual/interaction diff toolkit
- crawl-routes.ts: parse sitemap XML (flat + sitemapindex) → Route[]
- url-diff.ts: symmetric set diff (A △ B = ∅) hard gate for T18
- snapshot.ts: per-URL HTML capture (fetch mode); MCP screenshots documented
- dom-diff.ts: heading/links/codeblocks/components Jaccard ≥ 0.95
- visual-diff.ts: odiff-bin wrapper, 0.1% pixel threshold
- interaction-assertions.ts: theme/search/sidebar/copy/component checks (MCP ref)
- report.ts: aggregate results → dist-diff/report.md + report.json
- README.md: 5 layers + MCP-driven canonical flow

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 19:46:49 +08:00
twosugar c1b9ee1a0a refactor(migrate): extract mdx primitives into @longbridge/openapi-ui workspace package
- Add `"workspaces": ["packages/*"]` to root package.json
- Scaffold packages/ui with package.json (name: @longbridge/openapi-ui, v0.0.0) and tsconfig.json
- git mv 7 primitives from src/components/mdx/ to packages/ui/src/ (Tabs, TabItem, TipContainer, CliCommand, SDK, SDKLinks, Skill)
- Create packages/ui/src/index.ts barrel re-exporting all 7 components + Props types
- Update src/mdx-components.tsx to import all 7 from @longbridge/openapi-ui (single import line)
- No @lib/* / @styles/* / @components/* path aliases found in moved files; tsconfig.json requires no path overrides
- bun install links workspace package; astro check: 0 errors, 4 pre-existing hints

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 19:34:16 +08:00
twosugar ea57129682 feat(migrate): search — pagefind backend + vitepress-parity dialog UI
- Add pagefind@^1 to dependencies (used as CLI in build:* scripts via bunx)
- SearchButton: hosts Cmd+K / Ctrl+K / '/' (with form-field guard) global
  shortcuts; renders inline SVG search icon + ⌘K hint; manages open state
- SearchDialog: dynamic-imports /pagefind/pagefind.js at runtime with
  @vite-ignore; falls back to "Search is available after first production
  build" when import fails (dev env); debounced input (200 ms); locale
  filtering on raw result URLs; ↑↓/Enter keyboard navigation; Esc closes;
  backdrop click closes; body scroll locked while open; data-lbus-component
- SearchResults: renders listbox with active-index highlight; pagefind <mark>
  excerpt via dangerouslySetInnerHTML; empty state via t(locale,'search.empty')
- TopNav: import SearchButton; insert <SearchButton locale={locale} /> before
  <LanguageSwitcher /> in right-controls region

astro check: 5 pre-existing scripts/ errors, 0 new errors

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 19:07:57 +08:00
twosugar b7f43165e5 fix(migrate): declare picomatch as direct dependency
Region filter and remark plugin use picomatch directly. It was previously
a transitive dep of astro/vite/vitest, guarded by @ts-ignore. Declaring
it (plus @types/picomatch) removes the silent-break risk and eliminates
the type suppressions.
Ruling in
.superpowers/sdd/2026-08-17-astro-migration-stage-1/progress.md.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 18:30:57 +08:00
twosugar 6e1ea5c49c feat(migrate): content collection + slug resolver with parity tests
Wire src/content.config.ts to glob docs/{en,zh-CN,zh-HK}/**/*.mdx.
Implement resolveUrl/resolveLocale mirroring vitepress rewriteMarkdownPath
semantics; 16 unit tests cover index files, tri-lingual prefix, and
absolute/relative slug overrides.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 16:55:51 +08:00
twosugar 2d56fb5da3 feat(migrate): astro scaffold with react + mdx + tailwind + icon
Wire astro.config.ts, tsconfig paths, and a placeholder hello-world at
/ so `bun run dev` starts. Sitemap integration configured with tri-lingual
i18n; shikiConfig binds github-light/dark for later theme toggle.

Placeholder index.astro will be replaced by [...slug].astro in T5.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 16:28:38 +08:00
twosugar 45d60b9be1 chore(migrate): archive vitepress reference to .legacy/ and switch scripts to astro
Move vitepress config, theme, postcss and unocss configs into
.legacy/vitepress-reference/ for use as a source-of-truth reference
while we port components to React. Astro dependencies not yet
installed; scripts entry-points point to astro but running them will
fail until T2 lands astro.config.ts and dependencies.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-08-17 16:19:52 +08:00
Hogan d89e74990f docs: CLI v0.27.0 (agent + ACP) and CI build heap bump (#1208)
Non-grid slice split out of #1204 so it can ship independently (grid
trading is blocked on the gateway).

## Changes
- **Changelog & CLI release notes** (`en` / `zh-CN` / `zh-HK`) — a
2026-08-14 `CLI v0.27.0` entry documenting:
- **`agent` commands (A2A)** — `workspace list`, `agent list`, streaming
`agent chat` / `agent continue` (longbridge/longbridge-terminal#280)
- **`acp` runtime** — `longbridge acp` exposes the Longbridge AI agent
over the Agent Client Protocol, with Codex / Claude adapter presets
(longbridge/longbridge-terminal#282)
- **CI** — raise the docs build Node heap to 14GB (`package.json` +
`build.yml` + `canary.yml`).

## Not included
Grid trading docs (API reference, CLI `grid` page, SDK examples, push
event, MCP tools) stay in #1204 until the gateway is live.

Refs: longbridge/longbridge-terminal#280,
longbridge/longbridge-terminal#282
2026-08-14 17:43:26 +08:00
拉罐 4d758951cc feat: support US environment via cookie app_id (#1173)
Runtime US tenant detection based on cookie `app_id` /
`x-original-app-id` (longbridge_us / longbridge_us_uat), aligned with
openapi-website-private.

- API baseUrl (request.ts) prefers US host when cookie matches:
    longbridge_us     -> https://mr.longbridge.com
    longbridge_us_uat -> https://mr.longbridge-staging.com
  falls back to hostname suffix.
- __API_PROXY_URL__ resolves the same way in an inline bootstrap script
  that runs before longport-internal.iife.js loads.
- Append `with-us=1` to the login redirect URL.
- Pin longport-internal.iife.js to versioned CDN artifact that contains
  US tenant normalization

(assets.lbctrl.com/openapi-sdk/release/longport-internal-202607201728.iife.js).
- Rename portal gateway host m.* -> mr.* in package.json,
region.config.ts,
  config.mts and workflow yml.
2026-07-20 18:14:52 +08:00
hold-baby b952761fa6 Complete .com→.cn hostname rewrite for CN region build (#1100)
## Merge Verdict
**[APPROVE]** — Region URL rewriting is now complete across every
artifact channel; global build verified untouched.
> 6 files · +73 / -26 · `docs/.vitepress` `scripts/` `package.json`

---
## Summary
- Extract a shared `buildRegionUrlReplacements()` in `region-utils.ts`
that emits **four** rules per non-default hostname (protocol-prefixed +
bare-text for both `siteHostname` and `apiBaseUrl`), and route the four
pre-existing rewrite sites (`region-filter.ts`, `transformHtml`,
`buildEnd install`, plus the new ones) through it.
- Add a new Vite `region-source-url-rewrite` plugin (`enforce: 'pre'`)
that rewrites hardcoded hostnames inside `.vue/.ts/.json/.yaml` source
modules — this is the only channel that reaches Vite-compiled JS bundles
(install command strings in Vue components, `mcp-tools.json` connect
links, `openapi.yaml` error-message text).
- Bring `.md` copies + `llms.txt` into region rewriting:
`normalize_md.ts` (the real writer of `dist/**/*.md`) and
`generate-llms.ts` (the static `llms-intro.md` injection point) now
share the same helper.
- Fix root-cause env-leak: `build:cn` now also passes `VITE_REGION=cn`
to the `bun run build:llms` segment — previously `cross-env` only scoped
to the `vitepress build` process, so `normalize_md`/`generate-llms`
never knew it was a CN build and silently produced `.com` artifacts.

---
## Risk Analysis
| Risk | Level | Mitigation |
|------|-------|-----------|
| Global build (`build:release`) accidentally rewritten |  | Shared
helper returns `[]` when `VITE_REGION` is unset → every call site is a
no-op. Verified: `dist/longbridge-terminal/install.ps1` is
byte-identical to source; `mcp.html` keeps all 9 `.com`; `llms-full.txt`
keeps all 112 `open.longbridge.com`. |
| Bare-rule replacement double-matches |  | `open.longbridge.com` is
**not** a substring of `openapi.longbridge.com` (5th char `.` vs `a`),
so the four rules are mutually independent regardless of order. |
| Vite `transform` runs on every module — performance hit | 🟢 |
`buildRegionUrlReplacements()` is lightweight (one env read + small
array build). On global builds it short-circuits via
`replacements.length === 0`. |
| `enforce: 'pre'` ordering vs `yaml-transform` |  | `'pre'` plugins
run before normal plugins, so this transform sees raw YAML text and
rewrites it before `yaml-transform` JSON-stringifies it. |
| Hardcoded global hostnames in helper | 🟡 | Helper compares against the
literal `'https://open.longbridge.com'` /
`'https://openapi.longbridge.com'`. If the global domain ever changes,
this file plus `region.config.ts` must be updated together. Same
constraint already existed before this PR. |

---
## Design Decisions
- **Centralize rules in `region-utils.ts`** instead of inlining at four
call sites — four sites already drifted (HTML had two rules but markdown
had only the URL form before the previous PR). One source of truth
prevents future drift.
- **Pre-stage Vite transform** rather than a post-build dist scan —
keeps source maps intact and lets the rewrite participate in dependency
invalidation. It also naturally covers `openapi.yaml` (huge but fine —
string `split/join` is O(n) and only runs once per module per build).
- **Bare-hostname rules alongside URL rules** — covers
`[open.longbridge.com/connect](https://...)` markdown patterns where
only the link target gets matched by URL rules; the display text needs
the bare-host rule.
- **Source `install` / `install.ps1` keep `.com`** — global build's
`buildEnd` already had a rewrite pass; making source `.com`-default lets
the existing rewrite mechanism do the work and avoids two
source-of-truth files.

---
## Code Notes
1. **[Info]** `region-utils.ts:25` comment "first so bare rules don't
double-match"
In practice both orderings are correct because after either rule runs
the other one's "from" string no longer exists in the result. The note
is defensive rather than load-bearing.
   — Author note: deferred to next iteration.
2. **[Info]** `config.mts` Vite transform hook calls
`buildRegionUrlReplacements()` per module
The helper is cheap but is invoked once per source module on every
build. Could be hoisted to the closure top if profiling ever flags it;
not worth the structural change today.
   — Author note: deferred to next iteration.
3. **[Info]** `package.json` build:cn duplicates `cross-env
VITE_REGION=cn` across two segments
Maintainable but easy to forget if a third stage is added later. Could
be solved with `cross-env-shell` wrapping the whole chain, but that's a
separate cleanup.
   — Author note: deferred to next iteration.
4. **[Needs review]** Vite `transform` regex includes `.yaml`/`.yml`
This is intentional — `openapi.yaml` ships hardcoded
`https://open.longbridge.com/sdk` and error-message URLs that must be
rewritten for CN. Reviewer should confirm there's no other YAML in the
dependency graph whose `.com` strings must be preserved as global
references. None observed in the current tree.

---
## Verification
-  `bun run build:cn` succeeds; `rg -l
'(open|openapi)\.longbridge\.com' docs/.vitepress/dist` → **zero
residual `.com`** across HTML/MD/JS/scripts.
-  `bun run build:release` succeeds; `install.ps1` and `install` are
byte-identical to source; `mcp.html` keeps 9× `.com`; `llms-full.txt`
keeps 112× `open.longbridge.com`; CN endpoint mentions inside docs
(`getting-started.md` etc.) are preserved as intended.
-  `openapi-quote.longbridge.cn` / `openapi-trade.longbridge.cn` counts
in `getting-started.html` match source 1:1 (no over-rewrite).
- 📋 Reviewer to confirm: CN site (`open.longbridge.cn`) renders `mcp.md`
/ `skill/install` pages with the new URLs after deploy.

Co-authored-by: 袁昌瑞 <changrui.yuan@longbridge-inc.com>
2026-06-18 11:37:13 +08:00
拉罐 30401a857a feat: integrate Google One Tap login via CDN bundle (#1051)
Inject the `google-one-tap.es.js` CDN bundle into every page <head> via
VitePress `head` config, so it loads in both `bun run dev` and built
output (works around `transformHtml` being build-only).

- Gated by `VITE_REGION !== 'cn'` (Google unavailable in China).
- `data-proxy` attribute driven by `process.env.PROXY`: `canary` for
`dev:canary` / `build:canary`, otherwise `production`. CI inherits via
the same npm scripts — no workflow edits required.
- No `data-region` passed: the bundle falls back to `app-id` / `region`
cookies with `sg` default, which is correct for this first-party
`.longbridge.com` site.
- On success the bundle writes session cookies on `.longbridge.com` and
reloads, so `longportInternal.isLogin()` picks it up.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 10:38:18 +08:00
Hogan 6109102994 docs(fundamental): add business-segments, institution-rating-views, industry-rank, industry-peers, financial-report-snapshot (#999)
## Summary

Adds documentation for 6 new fundamental SDK APIs ported from
[longbridge-terminal PR
#202](https://github.com/longbridge/longbridge-terminal/pull/202).

**18 files created** across `zh-CN`, `zh-HK`, and `en`:

| API | SDK Method | Endpoint |
|-----|-----------|----------|
| Business Segments | `business_segments` | `GET
/v1/quote/fundamentals/business-segments` |
| Business Segments History | `business_segments_history` | `GET
/v1/quote/fundamentals/business-segments/history` |
| Institutional Rating Views | `institution_rating_views` | `GET
/v1/quote/ratings/institutional` |
| Industry Ranking | `industry_rank` | `GET /v1/quote/industry/rank` |
| Industry Peer Hierarchy | `industry_peers` | `GET
/v1/quote/industries/peers` |
| Financial Report Snapshot | `financial_report_snapshot` | `GET
/v1/quote/financials/earnings-snapshot` |

## Related PRs

- SDK (Rust): https://github.com/longbridge/openapi/pull/526
- SDK (Go): https://github.com/longbridge/openapi-go/pull/91

## Test plan

- [ ] Preview renders correctly for all 3 locales
- [ ] `<SDKLinks>` components resolve to correct methods
- [ ] `<CliCommand>` blocks display expected CLI invocations
- [ ] Response JSON examples and schema tables are accurate

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
2026-05-20 16:21:26 +08:00
Endless 89d39f2be1 feat: sync new SDK APIs from openapi to docs site (#962)
## Summary

Syncs new SDK interfaces introduced in openapi to the developers
documentation site, along with a range of docs, UI, and infrastructure
improvements.

## New API Documentation (EN / zh-CN / zh-HK)

### Quote APIs
- `option_volume` — option volume query
- `option_volume_daily` — daily option volume query
- `short_positions` — short position data
- `update_pinned` — update pinned securities

### Fundamental APIs
- **Calendar**: dividend, earnings, IPO, macro, split calendars
- **Fundamental**: company profile, corporate actions, dividends,
executives, financial reports, fund holdings, ratings, shareholders,
valuations
- **Market**: AH premium, broker positions, index components, market
status, trading stats, unusual items

### Account APIs
- **Alert**: create, delete, list, update alerts
- **DCA** (dollar-cost averaging): create, delete, list, update, history
- **Portfolio**: capital flow, exchange rates, profit analysis (by
market, detail, summary)
- **Sharelist**: create, delete, list, update share lists

## UI / Site Improvements

- **Pricing page**: new tri-locale pricing comparison page for market
data subscription tiers; fixes for responsive layout and static QR code
on mobile
- **FeaturesMenu**: mega-menu dropdown in main nav with 9 financial data
product categories; full i18n support
- **Nav**: moved API Reference from top nav to Docs sidebar (opens in
new tab)
- **Homepage visual polish**: neutral color vars on ArchCanvas, distinct
card accent hues, section border delineation, ProductSkill gradient,
flat GetStarted background
- **Quote permission**: added permission notices across CLI docs, API
docs, and API Reference; removed unreliable client-side permission
status detection
- **Mock login toggle**: dev-only panel to simulate login/logout state;
shared reactive `useLoginState` composable

## Docs Updates

- CLI v0.19.2 release notes + updated `finance-calendar` subcommand
examples
- Corrected quote permission names to match Quote Store (pluralization,
Nasdaq Basic rename)
- Updated skill guide to use CLI-first flow
- Fixed missing zh-HK translations

## Bug Fixes

- Fixed UnoCSS build error from arbitrary `font-feature-settings` class
- Added `result.root` null guard in `postcss.config.mjs` to prevent
PostCSS crash
- Fixed home page footer rendering
- Fixed pricing page build dist

🤖 Auto-generated by Endless.

---------

Co-authored-by: 老袁 Yuan Zhanghong <zhanghong.yuan@longbridge-inc.com>
Co-authored-by: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Jason Lee <huacnlee@gmail.com>
2026-05-14 18:13:11 +08:00
Endless 58d538852c feat: Add pricing page comparing market data subscription tiers (#951)
## Summary

Implements a dedicated pricing page similar to
[financialdatasets.ai/pricing](https://www.financialdatasets.ai/pricing)
that visually compares different market data subscription levels and
their capabilities.

## Changes

- **`Pricing.vue`**: New Vue component that displays market data
subscription tiers in a pricing comparison table format, highlighting
feature availability and pricing across different permission levels
- **`index.ts`**: Registers the new `Pricing` component for use in
VitePress pages
- **`docs/en/docs/pricing.md`**: English pricing page
- **`docs/zh-CN/docs/pricing.md`**: Simplified Chinese pricing page
- **`docs/zh-HK/docs/pricing.md`**: Traditional Chinese pricing page

## Motivation

Users need a clear way to understand what market data features are
available at each subscription tier and how the tiers differ in price
and capability. A pricing comparison page makes it easy to evaluate
which subscription level fits their needs.

🤖 Auto-generated by Endless.

---------

Co-authored-by: Huacnlee Li Huashun <huacnlee@longbridge-inc.com>
Co-authored-by: Jason Lee <huacnlee@gmail.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-07 21:30:02 +08:00
hogan 2dd452943a feat(mcp): promote MCP to top-level nav and add live tools list (#918)
## Summary

- Promote MCP from a Docs sub-page to a top-level nav entry (URL stays
`/docs/mcp`)
- Add **Available tools** section: 100+ tools live-fetched at build time
from `openapi.longbridge.com/mcp/tools.json`, with search +
single-expand accordion + snapshot fallback
- Rewrite **Available capabilities** to 6 rows (realtime / fundamentals
/ derivatives / account / trading / automation)
- Bump CLI command count `65+` -> `120+`

All changes synced across `en` / `zh-CN` / `zh-HK`.

## Test plan

- [ ] Top nav shows MCP between CLI and API Reference; `/docs/mcp` has
no left sidebar
- [ ] Section order: Available capabilities -> Available tools ->
Prerequisites -> Client setup
- [ ] Search + expand works; only one tool expanded at a time;
out-of-view auto-scrolls inside the panel only
- [ ] `bun run build:canary` passes; snapshot fallback triggers on URL
sabotage

---------

Co-authored-by: 袁章洪 <zhanghong.yuan@longbridge-inc.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 16:59:51 +08:00
ihavecoke b6e83e209a Rebuild homepage with new brand design system and interactive sections (#888)
## Summary

A complete overhaul of the Longbridge Developers homepage, introducing a
new brand design system built on inspira-ui animations, interactive
product showcases, and a unified multi-language content structure.

  ### New homepage sections
- **HeroSection** — Animated FlickeringGrid background, ColourfulText
rotating product showcase, interactive CTA buttons
- **PlatformStats** — 4 key stats with animated NumberTicker and hover
detail cards
- **CapSection** — Developer capability highlights with Spotlight +
Expand hover interaction
- **ArchSection** — Architecture diagram (custom SVG bus-topology) with
SdkMarquee
- **ProductCLI** — Interactive terminal mockup with real CLI output,
theme-aware (follows VitePress isDark), click-to-switch features
- **ProductMCP** — Custom SVG bus-topology diagram replacing VueFlow,
per-client config panels (shell/JSON/UI), tab sync with diagram
- **ProductSkill** — AI agent simulator with macOS traffic light dots
and install flow
- **ProductOpenAPI** — Bento Grid SDK showcase with Shiki syntax
highlighting, 6 SDKs × 4 domain code examples
  - **GetStarted** — Quick-start cards

  ### Design system additions
- 15+ inspira-ui animation components (`FlickeringGrid`,
`ColourfulText`, `NumberTicker`, `BorderBeam`, `Marquee`,
`AnimatedBeam`, etc.)
  - Tailwind CSS integration (`postcss.config.mjs`, `tailwind.css`)
- Unified section styles: consistent title/subtitle spacing (24px gap),
muted subtitle color, 14px minimum font size

  ### i18n
  - 150+ new keys added across `en.json`, `zh-CN.json`, `zh-HK.json`
  - All three locales kept in sync
2026-04-13 19:57:54 +08:00
hold-baby 267a813a7d feat(region): add China region build with page whitelist, URL rewriti… (#405)
…ng and independent deployment

Co-authored-by: 袁昌瑞 <changrui.yuan@longbridge-inc.com>
2026-04-03 21:33:12 +08:00
Jason Lee a222a0e781 build: copy skill/install routes to flat paths post-build (#388)
## Summary

- 新增 `scripts/copy-routes.ts` post-build 脚本,在构建完成后将
`skill/install/index.html` 和 `skill/install/index.md` 分别复制到
`skill/install.html` 和 `skill/install.md`
- 在 `build:canary` 和 `build:release` 命令末尾追加 `bun run
build:copy-routes`,确保每次构建自动执行

## 背景

部署服务器对 `.html` 有目录回退规则(`/skill/install` → `install.html` 或
`install/index.html`),但 `.md` 没有此规则,导致两种格式的访问路径不一致。此脚本确保两个位置的文件同时存在。

## Test plan

- [ ] 运行 `bun run build:canary` 或 `bun run build:release`,确认
`dist/skill/install.html` 和 `dist/skill/install.md` 均存在
- [ ] 确认 `dist/skill/install/index.html` 和 `dist/skill/install/index.md`
仍然存在

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 15:49:58 +08:00
Jason Lee b74f40145c docs: add Community content API docs (my-topics, create-topic) (#384)
## Summary

- Add `my_topics` and `create_topic` API reference pages in all 3
locales (en/zh-CN/zh-HK), using `<SDKLinks>` + `<Tabs>` pattern with
CLI, Python, Python async, Node.js, Java, Rust, C++, Go examples
- Rename Content sidebar category → **Community** across all locales
- Rename `security_topics` page title → "Get Community Topics by Symbol"
- Add Community content section to `cli.md` (all locales)
- Update `openapi.yaml`: add `x-codeSamples` for `list_my_topics` and
`create_topic`, fix `create_topic` schema (`title` not required at
schema level), move all community endpoints to `Community` tag
- Update CLI skill overview with `longbridge update` command details

## Key design notes

- `create_topic` page includes an article/post comparison table
explaining title requirement and body format differences
- SDK method signatures verified from source code
(`/Users/jason/work/openapi/`)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-25 19:21:52 +08:00
Jason Lee 6a4b543645 docs: Add openapi.yaml (#382)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:37:42 +08:00
Jason Lee 0add508ae2 feat: add Skill page with interactive demo (#376)
## Summary

- **New `/skill` page** with full trilingual support (en / zh-CN /
zh-HK)
- **Interactive chat demo**: 4 scenarios (Live Quote, Portfolio,
Subscription, Earnings) × 5 AI clients (OpenClaw, ChatGPT, Claude,
Claude Code, Codex) with typewriter animation
- **Rich response rendering**: tables with Shadcn-style borders, mini
SVG sparkline charts, syntax-highlighted code blocks
- **Scenario cards section** below the demo describing use cases
- **Nav update**: Skill link added to all three locale nav configs

## Bug Fixes

- **Syntax highlighter**: replaced chained-regex approach with a
single-pass tokenizer. The old code ran number → keyword → string
regexes sequentially on the same string — the keyword regex matched
`class` inside generated `<span class="hl-n">` attributes, and the
string regex matched `"hl-n"` as a string literal, corrupting the HTML
structure entirely
- **v-html routing**: replaced `currentMessages[2]?.rich` template
condition with an explicit `isRichResponse` ref set in `runAnimation()`
to prevent incorrect branch selection when switching client tabs

## Test plan

- [ ] Visit `/skill`, `/zh-CN/skill`, `/zh-HK/skill` — page loads in all
locales
- [ ] Click through all 4 scenario tabs — animation plays correctly for
each
- [ ] Click through all 5 client tabs — correct message shown, Claude
Code tab shows syntax-highlighted code (not raw HTML)
- [ ] Verify sparkline charts render in the Live Quote / OpenClaw
scenario
- [ ] Verify table borders render correctly (outer border + row
dividers, no missing bottom border)
- [ ] Verify gain/loss values show green/red colors in tables

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 20:03:14 +08:00
Jason Lee e7e9a2d1ba feat: Update platform name to Longbridge Developers and UI improvements (#369)
## Summary

- Rename project from "OpenAPI" to "Longbridge Developers" across all
locales, config, and docs
- Add local SVG assets for homepage features (replacing external CDN
URLs)
- **TipContainer**: replace emoji with SVG icons, Shadcn-style
border/bg/text per type using `data-type` + CSS `@apply`
- **Tabs**: improved tab styling, fix `ul`/`ol` indentation in tab
content
- **Sidebar**: active item uses brand color background (color-mix) with
rounded corners
- **Doc footer**: LLMs Text + Edit this page on same row, subdued
colors, lighter "Updated at"
- **Breadcrumb**: remove primary color
- **UserMenu**: rename Profile → Dashboard (控制台)
- **Style**: inline code color fix, blockquote updates, font
improvements

## Test plan

- [ ] Verify rename appears correctly in EN / zh-CN / zh-HK locales
- [ ] Check homepage SVGs load from `/assets/`
- [ ] Check TipContainer all 6 types render with correct
border/bg/text/icon colors in light and dark mode
- [ ] Check Tabs styling and list indentation
- [ ] Check sidebar active item background
- [ ] Check doc footer layout (LLMs Text + Edit this page same row)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 14:35:26 +08:00
Sunli 5accb00f24 docs: Longbridge SDK docs update (branding, 4.0.0, Go examples) (#356)
## Summary
- **Branding & version**: SDK 页与文档统一为 longbridge 品牌、版本 4.0.0,修正仓库与包地址
- **Getting started**: 更新 API Host、OAuth 示例与 4.0.0,修正 typo(开发中 → 开发者)
- **Request examples**: 为所有 API 请求示例补充多语言
tabs(Python/Node/Java/Rust/C++),并增加 Go SDK 示例(en / zh-CN / zh-HK)
- **Dependencies**: 更新 package.json 与 bun.lock

Made with [Cursor](https://cursor.com)
2026-03-11 11:34:49 +08:00
Geylnu f9a57355ce fix: configure API base URL for longport-internal SDK environment (#331)
Co-authored-by: 石石 <lei.yang@longbridge-inc.com>
2025-08-18 16:02:32 +08:00
Geylnu 58c6f7df4c Revert "feat: replace localStorage with Internal API for user information" (#330)
Reverts longportapp/openapi-website#329
2025-08-15 19:28:12 +08:00
Geylnu 35345af978 feat: replace localStorage with Internal API for user information (#329)
- Replace localStorage-based session management with LongPort Internal
API calls
- Add LongPort Internal SDK script injection via head tag and Vite
plugin
- Create TypeScript definitions for Internal SDK interfaces (UserInfo,
Member, Setting, etc.)
- Refactor UserAvatar component to use Internal API for user info and
login state
- Add useAvatar composable for fetching user avatar from Internal API
- Update UserAvatarIcon to handle empty avatar state with fallback
styling
- Include SDK type definitions in TypeScript compilation
- Update Node.js engine requirement to >=24.0.0
- Remove @ts-ignore comments for Vite plugins
-  Add Edit Link

Co-authored-by: 石石 <lei.yang@longbridge-inc.com>
2025-08-15 13:46:29 +08:00
hold-baby bb3123302c Release v2 (#328)
新增针对现有的 Http 接口提供了一个在线调试面板,可在线对当前 API
的参数进行调试,便于用户更直观的查看返回结果并提供复制和下载按钮。调试默认使用模拟账户的凭证,真实账户需要手动填写

---------

Co-authored-by: 石石 <lei.yang@longbridge-inc.com>
Co-authored-by: tzyoo <tzyitooo@gmail.com>
Co-authored-by: 袁昌瑞 <changrui.yuan@longbridge-inc.com>
2025-07-18 16:36:28 +08:00
Jason Lee 0517c68999 Upgrade Docusaurus v3.x (#253)
- [x] `@apply` 无法工作, https://github.com/facebook/docusaurus/issues/10005
- [x] `bun run build` 无法工作:`[ERROR] Client bundle compiled with errors
therefore further build is impossible.`
2025-04-02 18:05:33 +08:00
Jason Lee cfec198ff2 Remove Swagger, just use simple Markdown files. (#314) 2025-03-20 16:13:25 +08:00
Jason Lee 8a777a29c2 chore: Switch to use Bun to dev and build. (#312) 2025-03-20 14:15:43 +08:00
ihavecoke 3ed9935014 feat: Add support for llms.txt file deployment (#306) 2025-03-19 17:40:18 +08:00
ihavecoke 5c82112707 feat: Implement raw markdown file processing and distribution (#305) 2025-03-19 14:25:33 +08:00
Jason Lee 3db9fde5ed 重构 API 文档结构,给每个文件增加 SDK 的文件链接。 (#268)
<img width="903" alt="image"
src="https://github.com/longportapp/openapi-website/assets/5518/c26d8c42-ae93-4acb-9550-286a52bf210a">
2024-05-20 19:28:41 +08:00
Jason Lee 11764eb201 Upgrade Tailwind CSS v3.3 2023-03-29 11:01:26 +08:00
Jason Lee c23a5320b1 Upgrade docusaurus@v2.4.0 and improve theme. 2023-03-28 19:23:50 +08:00
Jason Lee e55425bef4 查找替换 Longbridge 改为 LongPort 2023-03-09 14:39:57 +08:00
王一旋 9be1568825 Use cross-env to inject env 2022-06-06 17:38:10 +08:00
王一旋 44bd7b4bc8 Add Tabs component
微调 Tabs 样式
2022-06-06 16:39:16 +08:00