The previous .gitignore un-ignored docs/superpowers/{plans,specs}/** wholesale,
so a broad `git add docs/` kept re-adding local planning docs (one failed
autocorrect CI on CJK punctuation). Simplified to ignore docs/superpowers/*
entirely and removed the six plan/spec files that slipped in. Already-tracked
astro-migration docs on main are unaffected (gitignore does not touch tracked
files).
The CLI --filter flag takes the bare indicator name (e.g. marketcap); it adds the
filter_ prefix internally before calling the gateway. Corrected the screener
search CLI examples in openapi.yaml and the screener .mdx pages from
--filter filter_marketcap:... to --filter marketcap:... (response keys still
carry the filter_ prefix — that is the raw wire field, unaffected).
The API Reference documents the raw HTTP response, so notes that explain how the
SDK/CLI reshape it are noise. Removed the 'JSON output format' warning on
screener_search and the 'SDK response' warning on screener_indicators, and fixed
the screener_indicators key description which wrongly said 'no filter_ prefix'
(the raw response keys DO carry the prefix, e.g. filter_market). Also simplified
the returns-param prefix wording to an example (e.g. `filter_pettm`).
An earlier `git add docs/` swept six untracked docs/superpowers plan and spec
files into the tree; one of them (2026-06-11-macroeconomic-docs.md) failed the
autocorrect CI on CJK-colon punctuation. These are local planning artifacts that
should not be version-controlled — removed from git (kept on disk).
industry_rank / industry_peers: response-example JSON counter_id -> symbol
(BK/US/IN00258 -> IN00258.US) and request-example query params counter_id ->
symbol. Same cleanup for grid_symbol_info request examples and top_movers /
valuation_comparison examples (dropping counter_id where a symbol sibling
already exists).
Only today_orders / history_orders retain counter_id: monitor_counter_id
(conditional-order monitor) and the order response's 'Counter order ID', both
intentionally kept.
NOTE: depends on longbridge-mcp#128 and longbridge-terminal#319 — do not publish
until both merge.
top_movers, valuation_comparison, industry_rank, industry_peers, cli
industry-rank/peers, and grid symbol_info now show symbol instead of the
internal counter_id, matching the openapi.yaml reference. Value examples
converted (ST/US/AAPL -> AAPL.US, BK/US/IN00258 -> IN00258.US); the top_movers
logo URL and the order files' 'Counter order ID' are intentionally untouched.
NOTE: this counter_id -> symbol migration depends on longbridge-mcp#128 and
longbridge-terminal#319 — the docs must not be published until BOTH PRs merge
(they move requests/responses to symbol end to end; until then production still
speaks counter_id).
industry_peers and grid_symbol_info query params counter_id -> symbol, matching
longbridge-terminal#319 and longbridge-mcp#128 which move every raw endpoint to
symbol-based requests. No counter_id request params remain in the reference.
Per decision, the max-profit/max-loss security identifiers are not exposed at
all — only the amounts (profit_max/loss_max) and display names (*_name) remain.
- screener_search: item counter_id -> symbol
- industry_rank: industry counter_id -> symbol (usable as symbol in industry_peers)
- industry_peers: sector counter_id -> symbol
- profit_analysis_summary: drop profit_max_counter_id / loss_max_counter_id
(profit_max_symbol / loss_max_symbol already present)
monitor_counter_id on today_orders / history_orders is intentionally kept.
The response 'key' field for screener_indicators and screener_strategy was
documented as 'no filter_ prefix', but the raw API actually returns keys WITH
the prefix (verified live: filter_market, filter_industry, ...) — the SDK strips
it. Corrected to show the real prefixed example instead.
Let the example value carry the meaning instead of explaining the prefix in
prose: indicator key descriptions now read 'e.g. `filter_pettm`' and the
filters param description drops the trailing '— the indicator key is prefixed
with filter_' clause (the `filter_<indicator>` example already shows it).
Verified against rust/src/trade/types.rs FundPosition: the account had no fund
holdings to capture live (empty list), so the field was cross-checked from the
Rust wire struct. holding_units was missing from the documented item shape.
today_orders and today_executions return the same Order/Execution types as
history_orders and history_executions (verified in rust/src/trade/context.rs),
and share the same wire response format. The account had no same-day data to
capture live, so their response fields are reused from the history_* siblings
(already rebuilt from live data).
Relaxed the empty-container guard so an endpoint whose top-level payload is
populated is regenerated even when a deeper array/object is empty in the sample
(the empty container is kept as a leaf field rather than discarding the whole
endpoint). This recovers history_orders (35 real fields, replacing 65
SDK-invented ones), screener_indicators (nested groups[].indicators[]),
index_components, business_segments_history, popular_sharelists, operating, and
others — all with field names/nesting from the real responses.
valuation and valuation_history are excluded from auto-regeneration (empty-string
metric key / per-symbol dynamic map) and will be handled manually.
etf_asset_allocation, us_etf_files, short_positions_us, short_trades_us —
re-captured with correct params/symbols (SPY.US for ETFs, AAPL.US for US short
data) and regenerated x-response-properties from the real responses.
The response definitions for 46 endpoints described the SDK-transformed shape
rather than the raw HTTP wire shape. Regenerated x-response-properties directly
from live API responses (captured with real credentials), so field names,
nesting, and types now match what the API actually returns.
Key corrections include: nested structures that were wrongly flattened
(valuation_comparison, industry_valuation, industry_valuation_dist,
financial_report_snapshot, us_company_dividends, us_valuation_overview,
security_facts, profit_analysis_summary), SDK-invented fields removed
(history-order fields, executives), and raw metric names restored
(price_close, market_value, div_yld, roe, net_margin, etc.).
counter_id policy: where the raw response carries both counter_id and a
sibling symbol, only symbol is documented; where counter_id is the sole
identifier it is kept.
Endpoints whose live sample contained an empty array/object (params could not
populate the data) were intentionally left untouched to avoid dropping
documented fields; those will be handled with correct params or manually.
Verified against the live API: the response is { total, items:[{ counter_id,
name, indicators:[{key,name,value,unit}] }] } — nested indicators, not the
flat SDK-transformed { symbol, pettm, marketcap, ... } that was documented.
Indicator keys carry the filter_ prefix and values are strings; the SDK strips
the prefix and the old docs described that transformed output. Also corrected
the JSON-output warning box and removed redundant hardcoded 'interface: POST ...'
lines duplicated across five screener endpoints (zh/zh-HK only).
option_volume_daily documented SDK-transformed names (call_volume, pc_vol,
date, top-level symbol) instead of the raw HTTP wire shape. The Rust SDK's
RawDailyStat deserializes total_call_volume/total_put_volume/
total_call_open_interest/total_put_open_interest/total_volume/
total_open_interest/put_call_volume_ratio/put_call_open_interest_ratio with a
per-record timestamp, and the top-level symbol is injected from the request
param (not in the response). Rewrote x-response-properties accordingly.
company_profile documented 'phone' but the wire field is 'Phone' (the SDK
maps it via #[serde(rename = "Phone")]).
Verified against the live API: docs had SDK-shaped/wrong response fields. Rewrite
to the actual raw shape:
- option_volume: c / p (docs wrongly said call_volume / put_volume)
- short_positions_hk/us, short_trades_hk/us: real data[] item fields (HK and US
differ; docs used one wrong shape for both)
- institution_rating: evaluate{}/target{}/industry_* (docs shape was entirely wrong)
counter_id (internal identifier, e.g. ST/HK/700) is not meaningful to API
consumers. Remove it from response properties of top_movers,
valuation_comparison, today_orders, history_orders. Kept for industry_rank /
industry_peers, which are counter_id-based endpoints; params left untouched.
Traditional Chinese nav/search used 文件 (file) for documentation; zh-CN uses
文档, so zh-HK should be 文檔. Fixes the top-nav Docs entry and the
nav.docs / nav.searchDocs / search.placeholder strings.
The language switcher used the server-rendered currentPath, which goes stale
after the API reference navigates client-side (pushState to /docs/api/<op>) —
switching locale dropped back to /docs/api. Read the live window.location when
the menu opens, and preserve any ?query (e.g. ?page=) across locales.
@types/markdown-it-container targets a different @types/markdown-it build, so
its plugin signature doesn't unify with our MarkdownIt instance — astro check
(tsc) failed. Cast it to the expected use() parameter type.
X-Timestamp is unix SECONDS, not milliseconds. Verified against a live API call
(seconds pass, ms fail the timestamp check) and the Rust SDK
(Timestamp::now() uses as_secs()). The headers table and all 7 signing
reference implementations (cURL/Python/Node/Java/Rust/C++/Go) computed
milliseconds — copying any of them produced a 403. Corrected to seconds.
list_alerts (GET /v1/notify/reminders), delete_alert (DELETE same),
list_sharelists (GET /v1/sharelists) and sharelist_remove_securities
(DELETE /v1/sharelists/{id}/items) were silently lost: an earlier
request-example regeneration rebuilt only body-bearing methods (post/put) for
each path and its removePaths+reinsert dropped the GET/DELETE siblings on those
multi-method paths. Restore them (verified against the Rust Path: doc-comments —
0 operations now missing) and clean their descriptions. 138 → 142 ops.
Make /docs/api/<operationId> the canonical shareable URL for an endpoint
(previously only /docs/api?op=<id> worked). The React app now reads the op from
the pathname (query ?op= kept as a fallback for old links) and pushes path URLs
on navigation. Add prerendered [op].astro routes (en + zh-CN/zh-HK) so direct
load, refresh, and sharing of /docs/api/<op> resolve — rendering the same
interactive reference, with the endpoint summary in the page title.
16 trade/asset ops had raw <br/><br/> / <br/> in param & response descriptions
(carried from docs table cells). With the reference's markdown-it html:false,
these rendered as literal '<br/>' in the CSR and .md. Convert consecutive <br/>
to '. ' (paragraph) and single <br/> to ', ' (inline enum lists) across 359
fields.
The request-example generator flattened nested body objects into malformed JSON
— e.g. submit_order emitted both "attached_params":{} and dotted top-level keys
"attached_params.attached_order_type", which an AI would send verbatim as a
wrong payload. Build real nested JSON from dotted param names (skipping the bare
container param), keyed by leaf name. Also strip the redundant 'Endpoint:
`METHOD /path`' line from 5 descriptions (the header already shows method+path).
Response-property descriptions carried docs-internal 'see [TypeName](#TypeName)'
links to Schema sections that don't exist in the reference (the nested fields
are already inlined below each object). Strip the dead anchors across 20 ops.
Un-escape literal \n / \{ \} carried from docs tables (e.g. create_topic
body/tickers) and strip relative cross-ref links [text](./x)/(../x) that don't
resolve in the reference (some pointed to the removed questionnaire endpoint),
keeping the link text.
'No request body fields defined in this spec' was misleading for paramless GET
endpoints (screener_indicators, rank_categories, list_watchlist_groups, etc.).
Reword to 'This endpoint takes no request parameters.' / 此接口无需请求参数。
10 content/AI ops (create_topic, create_topic_reply, ai_conversation,
topic_detail, list_topic_replies, list_news, list_topics, list_my_topics,
ai_public_agents, ai_workspace_agents) documented their params under
'## Request' > '### Path/Query Parameters' / '### Request Body' — a format the
original generators (which only read '## Parameters') skipped, so they showed
the empty-body fallback with no params. Extract them trilingually, reconcile
path-param names with the URL placeholders (docs 'id' → '{agent_id}'), and
regenerate raw-HTTP request examples.
list_securities, list_filings, list_market_temperature, market_temperature,
list_statements, get_statement_download_url and ai_continue were early
hand-authored entries using standard OpenAPI 'parameters' + x-codeSamples with
no x-parameters / x-request-examples / x-response-properties — so the reference
showed the empty-body fallback instead of a params table and emitted request
examples with no query/path substitution. Author trilingual x-parameters +
x-response-properties and regenerate raw-HTTP request examples for each.
Region warnings, tips, etc. were rendering as plain blockquotes in the
reference. Convert them back to ::: container syntax in the descriptions and
add a markdown-it-container plugin that emits the same DOM as the docs
remark-callout (.callout.callout-<type> + .callout-title), with the docs
callout.css copied into the package. Now :::warning/:::tip render as the same
colored boxes as docs; the .md keeps readable ::: blocks for AI consumers.
The reference's QuotePermission was rendering unstyled (plain text, no green
box / shield icon / badge pill) because its class names had no CSS and it only
supported 'command' (level-only watchlist ops rendered nothing). Port it 1:1
from the docs MDX component: shield icon, data-level color theming, market tag,
description, footer link + note; resolve command/level/market. Copy the docs
QuotePermission.css into the package and load it via api-reference.css.
Add x-subgroup (docs subsection) to every op and x-subgroups (ordered
subsection labels, trilingual) to each tag, so the reference sidebar nests
like the docs menu: e.g. 行情 > 个股行情/期权/数据分析/自选股, 交易 >
订单/网格交易/成交/资产. Screener stays flat (no docs subsections).
- Loader: SubGroup type; parseSpec partitions each tag's endpoints into
ordered subgroups (by op x-subgroup, ordered per tag x-subgroups) plus
leftover flat endpoints.
- ApiReference: nested collapsible subgroup level in the sidebar.
- openapi-markdown: render ## section > ### subsection > #### endpoint;
fix endpointList / endpointMarkdownById to include subgroup endpoints
(they previously only walked flat endpoints, 404-ing per-endpoint .md).
Retag every operation to its docs section (derived from the backing page's
top-level dir) so the reference menu mirrors the docs sidebar: Quote/行情,
Fundamental/基本面, Market/市场, News & Contents/资讯与社区, Screener/选股,
Trade/交易, Account/账户, AI Agent — trilingual, in docs order. Replaces the
prior function-based tags (Analytics/Assets/Grid/DCA/Alert/Signals/...).
The relative link '../trade-definition#ordertype|orderstatus' does not resolve
in the reference context (CSR page or per-endpoint .md), leaving the AI with no
enum values. Inline the full value list (33 param/response fields) so each
endpoint is self-contained.
Audited all 116 backing-page ops for special markers. Fixes:
- QuotePermission: render x-quote-command/level/market as a callout in BOTH
the CSR page and the AI markdown (openapi-markdown resolves
quote-permissions.yaml). Convert the 4 watchlist ops' leaked
'<QuotePermission level="basic" />' raw tags to x-quote-level: basic.
- Convert 2 topics ops' leaked '<TipContainer>' tags to blockquotes.
- Restore 3 admonitions dropped by the description cut / descOverride:
dca_toggle (US-account region warning), grid_trigger_history (uses
grid_order_id not order_id), ai_conversation (how to find an Agent UID).
- Loader: add x-quote-level / x-quote-market. CSR: pass level+market to
<QuotePermission>, render when any of command/level/market is set.
- Correct 5 endpoints' request params to true HTTP wire names (Rust does
client-side transforms): screener/search body (filters/returns/page/size),
broker-holding (add type), broker-holding/daily (parti_number),
ahpremium/klines (line_type/line_num), finance_calendar (date/date_end/
types[]/markets[]); fix finance_calendar response type wire name.
- Make POST examples executable: include full body (not just required) with
type-aware placeholders (arrays/ints/objects), so top_movers etc. no longer
emit an empty POST.
- Disambiguate duplicate summaries: short_positions/short_trades hk vs us now
carry market-specific titles.
- Strip embedded leading headings from descriptions (removes duplicate H1).
- Renderer: drop page-body heading that repeats the page title (fixes the
doubled '## Error Codes' in the aggregated api.md).