diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..a224cd8a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "openapi"] + path = openapi + url = https://github.com/longbridge/openapi +[submodule "openapi-go"] + path = openapi-go + url = https://github.com/longbridge/openapi-go +[submodule "longbridge-terminal"] + path = longbridge-terminal + url = https://github.com/longbridge/longbridge-terminal diff --git a/CLAUDE.md b/CLAUDE.md index 74f981d8..c24133bd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -11,115 +11,125 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Commands ```bash -# 开发(连接 canary 环境 API) -bun run dev +bun run dev # 开发(canary 环境 API) +bun run dev:prod # 开发(生产环境 API) +bun run build:canary # 构建 canary 环境 +bun run build:release # 构建生产环境 +bun run build:llms # 构建 llms.txt(在 build 之后执行) +bun run preview # 预览构建产物 +``` -# 开发(连接生产环境 API) -bun run dev:prod +无测试命令。 -# 构建 -bun run build:canary # canary 环境 -bun run build:release # 生产环境 +## 内容架构 -# 构建 llms.txt(在 build 之后单独执行) -bun run build:llms +本站分两类内容,定位不同: -# 预览构建产物 -bun run preview -``` +### Docs(`docs/{lang}/docs/`) -无测试命令,不需要跑测试。 +面向**业务场景**的使用指引。内容包括: -## 架构概览 +- 入门指南、认证流程 +- CLI 命令使用示例(用 `` 块) +- SDK 调用示例(Python / Rust / Go / Node.js / Java / C++) +- 功能介绍(行情、交易、账户、MCP、AI Skill 等) -这是一个基于 **VitePress 2.0 alpha** 的多语言文档网站,面向 Longbridge 开发者平台(open.longbridge.com)。 +Docs 页面以 en 为主,zh-CN / zh-HK 为翻译版本,三者内容保持一致。 -### 目录结构 +### API Reference(`docs/{lang}/api/`) -``` -docs/ -├── .vitepress/ -│ ├── config.mts # VitePress 主配置(含路由重写、HTML 注入) -│ ├── config/ -│ │ ├── locales.ts # 三语言 locale 聚合(en / zh-CN / zh-HK) -│ │ └── markdown.ts # Markdown 插件注册 -│ ├── locales/ # 每个语言的 nav / sidebar / search 配置 -│ │ ├── en/ -│ │ ├── zh-CN/ -│ │ └── zh-HK/ -│ ├── theme/ -│ │ ├── index.ts # 主题入口,注册全局组件和 vue-i18n -│ │ ├── components/ # Vue 组件(全局注册,可直接在 md 中使用) -│ │ ├── composables/ # Vue composables -│ │ ├── locales/ # i18n 翻译文件(en.json / zh-CN.json / zh-HK.json) -│ │ └── utils/ -│ │ └── gen.ts # 自动从文件系统生成 sidebar 的核心逻辑 -│ ├── md-plugins/ # 自定义 Markdown-it 插件 -│ └── utils.ts # 路由重写逻辑(处理 slug 和语言前缀) -├── en/ # 英文文档内容 -├── zh-CN/ # 简体中文文档内容 -└── zh-HK/ # 繁体中文文档内容 -scripts/ # 构建脚本(generate-llms.ts、normalize_md.ts 等) -``` +面向 **HTTP/WebSocket API** 的技术参考。以 `openapi.yaml` 为准: -### 多语言路由 +- 参数名称、类型、Required 字段必须与 `openapi.yaml` 完全一致 +- 响应结构、错误码以规范为准,不得自行发明 +- 更新 API 文档时,先改 `openapi.yaml`,再同步各语言页面 -- **英文**为 root locale(`/docs/...`),文件在 `docs/en/` -- **简中**路径为 `/zh-CN/docs/...`,文件在 `docs/zh-CN/` -- **繁中**路径为 `/zh-HK/docs/...`,文件在 `docs/zh-HK/` -- 路由重写由 `docs/.vitepress/utils.ts` 的 `rewriteMarkdownPath` 处理:支持 frontmatter `slug` 字段做绝对/相对路径覆盖 +## 三语言规则 -### Sidebar 自动生成 +每个 `.md` 页面必须在三个语言目录下都有对应文件: -Sidebar 通过 `docs/.vitepress/theme/utils/gen.ts` 的 `genMarkdowDocs(lang, basePath)` 自动从文件系统读取生成,无需手动维护。控制方式: +- `docs/en/` — 英文(root locale,URL 为 `/docs/...`) +- `docs/zh-CN/` — 简体中文(URL 为 `/zh-CN/docs/...`) +- `docs/zh-HK/` — 繁体中文(URL 为 `/zh-HK/docs/...`) -- **排序**:frontmatter `sidebar_position` 字段(数字越小越靠前) -- **分类标题**:子目录下的 `_category_.json`(`label`、`position`、`collapsed` 等) -- **自定义链接**:frontmatter `slug` 字段 -- **侧边栏图标**:frontmatter `sidebar_icon` 字段(支持 `book`、`zap`、`cpu`、`terminal`、`sparkles`) +**以 en 为主**,zh-CN / zh-HK 跟随 en 的结构和内容。新增或修改页面时,三个目录必须同步。 -### 新增页面流程 +### Frontmatter -每个 `.md` 文件需要在三个语言目录下各有一份(`en/`、`zh-CN/`、`zh-HK/`)。如果只在某个 locale 的 nav 中显示,需要同步修改对应的 `docs/.vitepress/locales/{lang}/nav.ts`。 +```yaml +--- +title: 'Page Title' +id: category_filename # 例:quote_pull-static +slug: '/quote/pull/static' # 以 / 开头,对应 URL 路径 +sidebar_position: 3 # 数字越小越靠前 +sidebar_icon: book # 可选:book | zap | cpu | terminal | sparkles +--- +``` -### 全局 Vue 组件 +## Skills -在 `docs/.vitepress/theme/components/index.ts` 中导出的组件会全局注册,可直接在 Markdown 中以标签形式使用: +`skills/longbridge/` 存放 AI Agent 的 Skill 文件。Skill 文件保持高层级描述,命令 flag 和输出细节参考 CLI 的 `--help`,不要复制 help 文本进 Skill。 -- `` / `` — 代码分组标签页 -- `` — 提示框 -- `` — API 在线调试 -- `` / `` — SDK 展示 -- `` — Skills 展示页 -- `` — 首页 +## 关联子模块 -新增组件需要在 `index.ts` 中 export。 +本项目通过 submodule 统一管理以下仓库,修改文档时需同步检查: -### 私有配套仓库 +| 仓库 | 用途 | 同步时机 | +| -------------------------------- | --------------------------------- | ------------------------- | +| `longbridge/openapi` | OpenAPI 规范源(`openapi/` 目录) | API 参数/响应变更时 | +| `longbridge/openapi-go` | Go SDK | API 方法签名/参数名变更时 | +| `longbridge/longbridge-terminal` | CLI 二进制 | CLI 命令/flag 变更时 | -`../openapi-website-private`(相对本项目)是配套私有仓库,存放不公开的功能实现(如开发者中心)。涉及相关改动时需检查两个仓库是否需要同步。 +`openapi.yaml`(根目录)是 API Reference 的权威来源,`openapi/` 目录下是各模块的分片 YAML。 -### Skills +## CliCommand 块 -`skills/` contains AI agent skill files. Currently includes skills for the Longbridge terminal: +在 Docs 中展示 CLI 命令使用 `` 标签,由 `docs/.vitepress/md-plugins/cli-command.ts` 渲染: +```markdown + +# 注释说明写在命令前面 +longbridge quote TSLA.US +# 可以有多个示例 +longbridge quote AAPL.US NVDA.US + ``` -skills/ -└── longbridge/ - ├── SKILL.md # skill entry point — tool selection and quick reference - └── references/ - ├── cli/overview.md # CLI usage overview (features, extended hours, etc.) - ├── python-sdk/ # Python SDK reference - ├── rust-sdk/ # Rust SDK reference - ├── llm.md # LLM/AI integration - └── mcp.md # MCP setup + +规则: + +- 注释行(`# ...`)放在对应命令**前面**,不用行尾注释 +- 每个 CliCommand 提供 2–4 个示例,使用真实 symbol(优先美股) +- 命令需实际验证正确后再写入文档(交易类命令除外) +- 尖括号占位符(如 ``)会被 Vue 解析为 HTML tag 导致构建失败,改用数字示例 + 注释说明 + +## Sidebar 自动生成 + +由 `docs/.vitepress/theme/utils/gen.ts` 的 `genMarkdowDocs()` 从文件系统自动生成,无需手动维护。子目录需有 `_category_.json`: + +```json +{ "position": 1, "label": "Market Data", "collapsed": false } ``` -**Documentation update rules:** +## 全局 Vue 组件 + +在 `docs/.vitepress/theme/components/index.ts` 中导出的组件可直接在 Markdown 中使用: + +| 组件 | 用途 | +| ---------------------- | ------------------------------ | +| `` / `` | 代码分组标签页 | +| `` | 提示框 | +| `` | API 在线调试 | +| `` / `` | SDK 链接展示 | +| `` | CLI 命令块(带高亮和安装引导) | +| `` | AI Skill 展示页 | +| `` | 首页 | + +新增组件需在 `index.ts` 中 export。 + +## 路由重写 -- All CLI docs, SDK references, and skill files for the Longbridge terminal (`../longbridge-terminal`) are maintained here in `skills/longbridge/` — `../longbridge-terminal` no longer has its own `skills/` directory. -- Skill files should stay high-level. For command flags and output details, defer to the CLI's built-in `--help` — do not copy help text into skill files. +`docs/.vitepress/utils.ts` 的 `rewriteMarkdownPath` 处理 URL 生成。`slug` frontmatter 覆盖默认路径:绝对 slug(`/foo`)替换整个路径;相对 slug 相对文件目录解析。 -### 图片/静态资源 +## 静态资源 -静态资源必须上传 CDN 后引用 URL,不要放进项目中。 +所有图片/静态文件必须上传 CDN 后引用 URL,不得放入仓库。 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3b2cb918..0e4c5e15 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,13 +32,15 @@ This is the source for **https://open.longbridge.com** — the official Longbrid │ ├── en/ # English content │ ├── zh-CN/ # Simplified Chinese content │ └── zh-HK/ # Traditional Chinese content +├── openapi/ # Submodule: github.com/longbridge/openapi +├── openapi-go/ # Submodule: github.com/longbridge/openapi-go +├── longbridge-terminal/ # Submodule: github.com/longbridge/longbridge-terminal ├── skills/ │ └── longbridge/ │ └── SKILL.md # The AI Skill for Longbridge APIs ├── scripts/ # Build scripts │ ├── generate-llms.ts # Generates llms.txt │ └── normalize_md.ts # Normalizes Markdown formatting -├── openapi/ # OpenAPI specifications (YAML) ├── CONTRIBUTING.md # This file └── package.json ``` @@ -212,21 +214,69 @@ The `docs/.vitepress/utils.ts` `rewriteMarkdownPath` function handles URL genera --- -## Related Repositories +## Submodules -When making changes that affect the API surface, check whether these related repositories need corresponding updates: +This repo includes three submodules for unified cross-repo development. Always `cd` into the submodule directory to make changes there — commits must be made inside the submodule, then the parent repo updated to reference the new commit. -### [`longbridge/openapi`](https://github.com/longbridge/openapi) +```bash +# Initialize after cloning +git submodule update --init --recursive + +# Update all submodules to latest +git submodule update --remote --merge +``` + +### [`openapi/`](https://github.com/longbridge/openapi) — OpenAPI & SDK source + +Contains the canonical OpenAPI specification and multi-language SDK source code (Python, Rust, Go, Node.js, Java, C++). + +**Sync when:** +- An API endpoint is added, removed, or its parameters/response shape changes +- A new SDK language is added +- An existing SDK method is renamed or its signature changes + +**What to change:** +- `openapi/openapi.yaml` — the authoritative API spec; all other changes derive from this +- SDK source files for any affected method across all languages + +### [`openapi-go/`](https://github.com/longbridge/openapi-go) — Go SDK + +The official Go SDK. Method names, parameter types, and response structs must stay consistent with what is documented in `docs/{lang}/` and defined in `openapi/openapi.yaml`. + +**Sync when:** +- An API method signature changes (parameter added/removed/renamed) +- A new endpoint is added that needs a Go implementation +- Response struct fields change + +**What to change:** +- Go struct definitions and method signatures in `openapi-go/` +- Ensure Go method names in `SDKLinks` component (`docs/.vitepress/theme/components/SDKLinks.vue`) match + +### [`longbridge-terminal/`](https://github.com/longbridge/longbridge-terminal) — CLI binary + +The `longbridge` CLI distributed via Homebrew. CLI docs (`docs/{lang}/docs/cli.md`) and `` examples in API docs must reflect the actual CLI behavior. -The canonical OpenAPI specification source. The `openapi/` directory in this repo may mirror or derive from it. If the API schema changes, both repos may need updating. +**Sync when:** +- A new CLI command or flag is added +- A command's output format or behavior changes +- A command is deprecated or removed -### [`longbridge/openapi-go`](https://github.com/longbridge/openapi-go) +**What to change:** +- CLI source in `longbridge-terminal/` +- `docs/{lang}/docs/cli.md` in all three locales +- Any `` blocks in docs that use the affected command +- `skills/longbridge/references/cli/overview.md` -The official Go SDK. Reflects the same API surface documented here. If you update API docs, check whether the Go SDK's method signatures, parameter names, or response types are consistent with what's documented. +### Cross-repo change workflow -### [`longbridge/longbridge-terminal`](https://github.com/longbridge/longbridge-terminal) +When a change touches multiple repos (e.g., a new API endpoint): -The `longbridge` CLI binary (distributed via Homebrew). CLI reference docs at `docs/{lang}/cli.md` must accurately reflect the CLI's actual commands and flags. When documenting CLI features, verify against the terminal repo. +1. Update `openapi/openapi.yaml` (API spec) +2. Update SDK implementations in `openapi/` and `openapi-go/` as needed +3. Update CLI in `longbridge-terminal/` if a new command is needed +4. Update `docs/{lang}/` pages (all three locales) with new `` examples and SDK request examples +5. Update `skills/longbridge/SKILL.md` if the AI Skill needs to know about the new endpoint +6. Commit each submodule separately, then update the parent repo's submodule reference --- @@ -262,6 +312,7 @@ Before submitting a PR, verify: - [ ] Frontmatter is present and correct (`title`, `id`, `slug`, `sidebar_position`) - [ ] No images or static assets added to the repo (use CDN URLs) - [ ] If a new component was added, it is exported from `theme/components/index.ts` -- [ ] If the API surface changed, `openapi/` YAML and the AI Skill (`skills/longbridge/SKILL.md`) are updated -- [ ] Related repositories are checked for consistency +- [ ] If the API surface changed: `openapi/openapi.yaml`, SDK source in `openapi/` and `openapi-go/`, and `skills/longbridge/SKILL.md` are updated +- [ ] If CLI commands changed: `longbridge-terminal/` source, `docs/{lang}/docs/cli.md`, and affected `` blocks are updated +- [ ] Submodule commits are made inside the submodule directory; parent repo references the new commit - [ ] Markdown formatting is clean (run `autocorrect --fix .` for Chinese/English spacing) diff --git a/README.md b/README.md index 952e3dc4..d5955e4f 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,26 @@ Longbridge Developers is the official developer platform for Longbridge — prov --- +## Repository structure + +``` +/ +├── docs/ # Site content and VitePress config +│ ├── .vitepress/ # Theme, components, markdown plugins, locale configs +│ ├── en/ # English content (root locale) +│ ├── zh-CN/ # Simplified Chinese content +│ └── zh-HK/ # Traditional Chinese content +├── openapi/ # Submodule: OpenAPI spec + SDK source (openapi, Python, Rust, etc.) +├── openapi-go/ # Submodule: Go SDK +├── longbridge-terminal/ # Submodule: CLI binary source (longbridge) +├── skills/longbridge/ # AI Skill — knowledge base for AI agents +├── scripts/ # Build scripts (llms.txt generation, markdown normalization) +├── openapi.yaml # Canonical API specification (source of truth for API Reference) +└── CONTRIBUTING.md # Contribution guidelines for AI agents and humans +``` + +--- + ## What you can build - Automated trading strategies and order management @@ -15,13 +35,13 @@ Longbridge Developers is the official developer platform for Longbridge — prov ## Access methods -| Method | Best for | -|--------|----------| -| [SDK](https://open.longbridge.com/sdk) | Python, Rust, Node.js, Go, Java, C++ apps | -| [HTTP / WebSocket API](https://open.longbridge.com/api) | Any language, custom integrations | -| [CLI](https://open.longbridge.com/cli) (`longbridge`) | Terminal workflows, scripting, AI tool-calling | -| [MCP](https://open.longbridge.com/mcp) | AI coding assistants (Cursor, Claude, ChatGPT, etc.) | -| [Skill](https://open.longbridge.com/skill) | Give any AI direct knowledge of Longbridge APIs | +| Method | Best for | +| ------------------------------------------------------- | ---------------------------------------------------- | +| [SDK](https://open.longbridge.com/sdk) | Python, Rust, Node.js, Go, Java, C++ apps | +| [HTTP / WebSocket API](https://open.longbridge.com/api) | Any language, custom integrations | +| [CLI](https://open.longbridge.com/cli) (`longbridge`) | Terminal workflows, scripting, AI tool-calling | +| [MCP](https://open.longbridge.com/mcp) | AI coding assistants (Cursor, Claude, ChatGPT, etc.) | +| [Skill](https://open.longbridge.com/skill) | Give any AI direct knowledge of Longbridge APIs | ## Quick start @@ -69,11 +89,11 @@ npx skills add longbridge/developers -g -y ## Market coverage -| Market | Instruments | -|--------|-------------| -| Hong Kong | Equities, ETFs, Warrants, CBBCs, Hang Seng Index | -| United States | Stocks, ETFs, OPRA Options, Nasdaq Index | -| China A-share | Stocks, ETFs, Index | +| Market | Instruments | +| ------------- | ------------------------------------------------ | +| Hong Kong | Equities, ETFs, Warrants, CBBCs, Hang Seng Index | +| United States | Stocks, ETFs, OPRA Options, Nasdaq Index | +| China A-share | Stocks, ETFs, Index | ## Documentation @@ -106,4 +126,22 @@ OpenAPI access is free for Longbridge Integrated Account holders. No additional ## Contributing -See [CONTRIBUTING.md](./CONTRIBUTING.md). +### Local development setup + +```bash +git clone --recurse-submodules https://github.com/longbridge/developers.git +cd developers +bun install +bun run dev +``` + +If you already cloned without `--recurse-submodules`: + +```bash +git submodule update --init --recursive +bun run dev +``` + +The dev server starts at `http://localhost:5173` and connects to the canary API. Use `bun run dev:prod` to connect to the production API instead. + +See [CONTRIBUTING.md](./CONTRIBUTING.md) for full contribution guidelines. diff --git a/docs/.vitepress/config/markdown.ts b/docs/.vitepress/config/markdown.ts index fc45252b..bde7b442 100644 --- a/docs/.vitepress/config/markdown.ts +++ b/docs/.vitepress/config/markdown.ts @@ -3,6 +3,7 @@ import { groupIconMdPlugin } from 'vitepress-plugin-group-icons' import { tipContainerPlugin } from '../md-plugins/tip-container' import { GenTryItPlugin } from '../md-plugins/gen-try-it.ts' import { NormalizeMdPlugin } from '../md-plugins/normalize-md' +import { CliCommandPlugin } from '../md-plugins/cli-command' export const markdownConfig: MarkdownOptions = { image: { @@ -51,5 +52,6 @@ export const markdownConfig: MarkdownOptions = { md.use(groupIconMdPlugin) md.use(tipContainerPlugin) md.use(GenTryItPlugin) + md.use(CliCommandPlugin) }, } diff --git a/docs/.vitepress/md-plugins/cli-command.ts b/docs/.vitepress/md-plugins/cli-command.ts new file mode 100644 index 00000000..1e4d6090 --- /dev/null +++ b/docs/.vitepress/md-plugins/cli-command.ts @@ -0,0 +1,130 @@ +import type MarkdownIt from 'markdown-it' + +function escapeHtml(str: string): string { + return str + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') +} + + +function getInstallLabel(localeIndex: string): string { + switch (localeIndex) { + case 'zh-CN': return '安装 CLI' + case 'zh-HK': return '安裝 CLI' + default: return 'Install CLI' + } +} + +function getInstallUrl(localeIndex: string): string { + switch (localeIndex) { + case 'zh-CN': return '/zh-CN/docs/cli' + case 'zh-HK': return '/zh-HK/docs/cli' + default: return '/docs/cli' + } +} + +// Colors matching github-light / github-dark shiki themes (auto-switch via CSS vars) +const C = { + binary: 'style="--shiki-light:#6f42c1;--shiki-dark:#b392f0"', // purple + subcmd: 'style="--shiki-light:#005cc5;--shiki-dark:#79b8ff"', // blue + args: 'style="--shiki-light:#24292e;--shiki-dark:#e1e4e8"', // default text +} as const + +// Colors for inline comments (the # ... part at end of a command line) +const C_comment = 'style="--shiki-light:#6a737d;--shiki-dark:#6a737d"' // gray + +function renderLine(line: string): string { + const trimmed = line.trim() + if (!trimmed) return '' + + // Pure comment lines (start with #) + if (trimmed.startsWith('#')) { + return `${escapeHtml(trimmed)}` + } + + // Split command from inline comment (# ...) + const commentIdx = trimmed.indexOf(' #') + const command = commentIdx >= 0 ? trimmed.slice(0, commentIdx).trimEnd() : trimmed + const comment = commentIdx >= 0 ? trimmed.slice(commentIdx) : '' + + const parts = command.split(/\s+/) + if (parts[0] !== 'longbridge') { + return `${escapeHtml(command)}${comment ? `${escapeHtml(comment)}` : ''}` + } + + let html = `${escapeHtml(parts[0])}` + if (parts.length > 1) { + html += ` ${escapeHtml(parts[1])}` + if (parts.length > 2) { + html += ` ${escapeHtml(parts.slice(2).join(' '))}` + } + } + if (comment) { + html += `${escapeHtml(comment)}` + } + return html + '' +} + +function generateCliBlock(content: string, installLabel: string, installUrl: string): string { + const lines = content + .split('\n') + .map(renderLine) + .filter(Boolean) + .join('\n') + + return ( + `
` + + `

CLI${escapeHtml(installLabel)}

` + + `
` + + `bash` + + `
` +
+    `${lines}
` + + `
` + ) +} + +function replaceCliCommand(src: string, installLabel: string, installUrl: string): string { + return src.replace( + /([\s\S]*?)<\/CliCommand>/g, + (_, content: string) => generateCliBlock(content.trim(), installLabel, installUrl), + ) +} + +export function CliCommandPlugin(md: MarkdownIt) { + md.core.ruler.push('cli_command', (state) => { + const localeIndex: string = state.env?.localeIndex ?? 'root' + const installLabel = getInstallLabel(localeIndex) + const installUrl = getInstallUrl(localeIndex) + + let i = 0 + while (i < state.tokens.length) { + const token = state.tokens[i] + + // Case 1: already an html_block (e.g. multiline ) + if (token.type === 'html_block' && token.content.includes('')) { + token.content = replaceCliCommand(token.content, installLabel, installUrl) + i++ + continue + } + + // Case 2: single-line parsed as paragraph > inline + if ( + token.type === 'paragraph_open' && + state.tokens[i + 1]?.type === 'inline' && + state.tokens[i + 1].content.includes('') && + state.tokens[i + 2]?.type === 'paragraph_close' + ) { + const replaced = replaceCliCommand(state.tokens[i + 1].content, installLabel, installUrl) + const htmlToken = new state.Token('html_block', '', 0) + htmlToken.content = replaced + state.tokens.splice(i, 3, htmlToken) + i++ + continue + } + + i++ + } + }) +} diff --git a/docs/.vitepress/theme/components/CliCommand.vue b/docs/.vitepress/theme/components/CliCommand.vue new file mode 100644 index 00000000..07c6d2b6 --- /dev/null +++ b/docs/.vitepress/theme/components/CliCommand.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/docs/.vitepress/theme/components/Skill.vue b/docs/.vitepress/theme/components/Skill.vue index 84c68101..579e127a 100644 --- a/docs/.vitepress/theme/components/Skill.vue +++ b/docs/.vitepress/theme/components/Skill.vue @@ -1,6 +1,7 @@ - - - - -``` - -- [ ] **Step 2: Verify the import path is correct** - -From `docs/.vitepress/theme/components/`, four `../` hops reach the project root where `openapi.yaml` lives: -- `../` → `docs/.vitepress/theme/` -- `../../` → `docs/.vitepress/` -- `../../../` → `docs/` -- `../../../../` → project root ✓ - -No change needed. - -- [ ] **Step 3: Commit** - -```bash -git add docs/.vitepress/theme/components/ApiReference.vue -git commit -m "feat: add custom ApiReference Vue component" -``` - ---- - -## Task 4: Wire into LayoutInner.vue and remove ScalarApiReference.vue - -**Files:** `docs/.vitepress/theme/layouts/LayoutInner.vue`, `docs/.vitepress/theme/components/ScalarApiReference.vue` - -- [ ] **Step 1: Update the import in LayoutInner.vue** - -In `docs/.vitepress/theme/layouts/LayoutInner.vue`, find line 19: - -```ts -import ScalarApiReference from '../components/ScalarApiReference.vue' -``` - -Replace with: - -```ts -import ApiReference from '../components/ApiReference.vue' -``` - -- [ ] **Step 2: Update the template usage in LayoutInner.vue** - -Find line 94: - -```vue - -``` - -Replace with: - -```vue - -``` - -- [ ] **Step 3: Delete ScalarApiReference.vue** - -```bash -rm docs/.vitepress/theme/components/ScalarApiReference.vue -``` - -- [ ] **Step 4: Commit** - -```bash -git add docs/.vitepress/theme/layouts/LayoutInner.vue -git rm docs/.vitepress/theme/components/ScalarApiReference.vue -git commit -m "feat: wire ApiReference into layout, remove ScalarApiReference" -``` - ---- - -## Task 5: Verify in dev server - -- [ ] **Step 1: Start dev server** - -```bash -bun run dev -``` - -Wait for `➜ Local: http://localhost:5173/` (port may vary). - -- [ ] **Step 2: Open the API reference page** - -Open `http://localhost:5173/docs/api` in a browser. - -Expected: -- VitePress top nav visible with "API" entry highlighted -- Left sidebar shows endpoint groups (Watchlist Management, Market Data, etc.) -- First endpoint auto-selected: "Get Watchlist Group List" -- Top half shows method badge + path + description prose -- Bottom half shows `shell` cURL code block and `json` response code block -- Code blocks have no shadow, match doc style - -- [ ] **Step 3: Test sidebar resize** - -Drag the divider line left and right. -Expected: sidebar width changes smoothly between 160px and 400px. - -- [ ] **Step 4: Test sidebar collapse** - -Click the `‹` toggle button. -Expected: sidebar collapses to zero width. Click `›` to restore. -Refresh the page — sidebar should restore to last saved width (localStorage persistence). - -- [ ] **Step 5: Test dark mode** - -Toggle the VitePress dark mode switch. -Expected: entire page including sidebar and code blocks switches theme correctly. - -- [ ] **Step 6: Check zh-CN route** - -Open `http://localhost:5173/zh-CN/docs/api`. -Expected: same API reference renders (spec is English only). - -- [ ] **Step 7: Final commit if any fixups were needed** - -```bash -git add -A -git commit -m "fix: api reference integration fixups" -``` diff --git a/docs/superpowers/plans/2026-03-24-scalar-api-reference.md b/docs/superpowers/plans/2026-03-24-scalar-api-reference.md deleted file mode 100644 index e41ca9b9..00000000 --- a/docs/superpowers/plans/2026-03-24-scalar-api-reference.md +++ /dev/null @@ -1,429 +0,0 @@ -# Scalar API Reference Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Add an interactive OpenAPI reference page at `/docs/api` using Scalar, with OAuth 2.0 + PKCE Try It support. - -**Architecture:** A new `ScalarApiReference.vue` component wraps `@scalar/api-reference`. `LayoutInner.vue` gains a third layout branch (`frontmatter.layout === 'api-reference'`) alongside the existing `showTryIt` branch. Three minimal `api.md` entry files (one per locale) trigger this layout. - -**Tech Stack:** `@scalar/api-reference` (Vue 3 component), VitePress 2.0 alpha, Vite `?raw` import, OAuth 2.0 Authorization Code + PKCE. - -**Note:** This project has no test suite. Verification is done with `bun run dev` and browser inspection. - ---- - -## File Map - -| Action | File | -|--------|------| -| Modify | `openapi.yaml` | -| Create | `docs/.vitepress/theme/components/ScalarApiReference.vue` | -| Modify | `docs/.vitepress/theme/layouts/LayoutInner.vue` | -| Create | `docs/en/docs/api.md` | -| Create | `docs/zh-CN/docs/api.md` | -| Create | `docs/zh-HK/docs/api.md` | -| Modify | `docs/.vitepress/locales/en/nav.ts` | -| Modify | `docs/.vitepress/locales/zh-CN/nav.ts` | -| Modify | `docs/.vitepress/locales/zh-HK/nav.ts` | -| Modify | `package.json` (via bun add) | - ---- - -## Task 1: Install dependency - -**Files:** `package.json`, `bun.lock` - -- [ ] **Step 1: Install `@scalar/api-reference`** - -```bash -bun add @scalar/api-reference -``` - -Expected: package added to `dependencies` in `package.json`. - -- [ ] **Step 2: Commit** - -```bash -git add package.json bun.lock -git commit -m "chore: add @scalar/api-reference" -``` - ---- - -## Task 2: Add `securitySchemes` to `openapi.yaml` - -**Files:** `openapi.yaml` - -`openapi.yaml` already has a `components:` section at line 2784 with `schemas:` (including `Error` and `Order`). We need to: -1. Add `security:` at the top level (before `paths:` at line 24) -2. Add `securitySchemes:` as a sibling of `schemas:` inside the existing `components:` block - -Do NOT create a new `components:` block — that would duplicate the key and produce invalid YAML. - -- [ ] **Step 1: Add `security` field before `paths:` (line 24)** - -Insert these two lines immediately before the `paths:` line: - -```yaml -security: - - oauth2: - - openapi -``` - -- [ ] **Step 2: Add `securitySchemes` inside the existing `components:` block** - -The existing `components:` block starts at line 2784: -```yaml -components: - schemas: - Error: - ... -``` - -Insert `securitySchemes:` as a new sibling of `schemas:`, so the block becomes: - -```yaml -components: - securitySchemes: - oauth2: - type: oauth2 - flows: - authorizationCode: - authorizationUrl: https://openapi.longbridge.com/oauth2/authorize - tokenUrl: https://openapi.longbridge.com/oauth2/token - scopes: - openapi: Full OpenAPI access - schemas: - Error: - ... (existing content unchanged) -``` - -Use the Edit tool to insert just the `securitySchemes:` block between `components:` and ` schemas:`. - -- [ ] **Step 3: Verify YAML is parseable** - -```bash -npx --yes js-yaml openapi.yaml > /dev/null && echo "YAML OK" -``` - -Expected: prints `YAML OK` with no errors. - -- [ ] **Step 4: Commit** - -```bash -git add openapi.yaml -git commit -m "feat: add OAuth2 securitySchemes to openapi.yaml" -``` - ---- - -## Task 3: Create `ScalarApiReference.vue` - -**Files:** `docs/.vitepress/theme/components/ScalarApiReference.vue` - -- [ ] **Step 1: Create the component** - -```vue - - - - - -``` - -- [ ] **Step 2: Verify the import path resolves** - -From `docs/.vitepress/theme/components/`, four `../` hops reach the project root: -- `../` → `docs/.vitepress/theme/` -- `../../` → `docs/.vitepress/` -- `../../../` → `docs/` -- `../../../../` → project root (where `openapi.yaml` lives) - -This is correct. No changes needed. - -- [ ] **Step 3: Commit** - -```bash -git add docs/.vitepress/theme/components/ScalarApiReference.vue -git commit -m "feat: add ScalarApiReference Vue component" -``` - ---- - -## Task 4: Add `api-reference` layout branch to `LayoutInner.vue` - -**Files:** `docs/.vitepress/theme/layouts/LayoutInner.vue` - -The existing layout already has a `v-if="!showTryIt"` / `v-else` pattern for the main content area. The sidebar and local nav need to be hidden for the API reference layout, and Scalar rendered instead. - -- [ ] **Step 1: Add import for `ScalarApiReference` at the top of the `