+
+
+ AWARD
+
+
+
+
Each winner receives 10,000 Task Coins + 1 × AirPods 4
+
+ Winning cases are showcased on the Longbridge Skill website — visible to users worldwide, including the
+ winner's ID and creative work.
+
+
+
+
+
+
AirPods 4
+
PER WINNER
+
+
+
-TSLA.US Tesla, Inc.
$380.85 -$7.68 (-1.98%)
-
-
$ longbridge submit-order TSLA.US --type trailing-stop --trail-pct 8 --side sell --qty all --preview
-
-
订单预览 · 未提交
-
──────────────────────────────────────────────
-类型: 追踪止损单 (Trailing Stop)
-方向:
SELL
-标的: TSLA.US
-追踪比例:
8.00%
-参考价: $380.85
-触发价:
$350.38 # $380.85 × (1 − 0.08)
-执行方式: 触发后市价成交
-
──────────────────────────────────────────────
-
# 价格每上涨 $1,触发价同步上移 $0.92
-
# 确认提交:longbridge submit-order ... --confirm
-
🔒 等待确认,尚未提交`),
- },
- ],
- },
- },
-
- // ── 6. 持仓复盘
- {
- id: 'coding',
- label: isEN.value ? 'Portfolio Review' : isHK.value ? '持倉複盤' : '持仓复盘',
- messages: [
- {
- role: 'user',
- content: isEN.value
- ? 'Review my portfolio this month: total P&L trend, top contributor, worst performer, US vs HK allocation?'
- : isHK.value
- ? '幫我複盤這個月的持倉表現:總盈虧趨勢如何,哪隻股票貢獻最大、哪隻表現最弱,組合裡美股和港股各佔多少?'
- : '帮我复盘这个月的持仓表现:总盈亏趋势如何,哪只股票贡献最大、哪只表现最弱,组合里美股和港股各占多少?',
- },
- {
- role: 'tool',
- command: 'longbridge positions && longbridge profit --from 2026-03-01 --to 2026-03-24',
- content: '',
- },
- {
- role: 'assistant',
- rich: true,
- content: `
-
-
${
- isEN.value ? 'March P&L' : hk ? '3 月總盈虧' : '3 月总盈亏'
- }
-$4,287
-4.8%
-
${
- isEN.value ? 'Best' : '最佳'
- }
9618.HK
+5.8%
-
${
- isEN.value ? 'Worst' : '最弱'
- }
9988.HK
-9.7%
-
-
-
- | ${isEN.value ? 'Symbol' : hk ? '代碼' : '代码'} |
- ${isEN.value ? 'Name' : hk ? '名稱' : '名称'} |
- ${isEN.value ? 'Mar 1' : hk ? '月初價' : '月初价'} |
- ${isEN.value ? 'Now' : hk ? '當前價' : '当前价'} |
- ${isEN.value ? 'MTD%' : hk ? '月漲跌' : '月涨跌'} |
- ${isEN.value ? 'Contrib' : hk ? '貢獻' : '贡献'} |
-
-
- | 9618.HK | ${
- isEN.value ? 'JD.com' : hk ? '京東集團' : '京东集团'
- } | HK$101.30 | HK$107.20 | +5.8% | +$412 |
- | NVDA.US | NVIDIA | $182.48 | $175.64 | -4.1% | -$691 |
- | MSFT.US | Microsoft | $398.55 | $379.85 | -4.7% | -$281 |
- | AAPL.US | Apple | $264.72 | $249.66 | -5.7% | -$2,003 |
- | 700.HK | ${
- isEN.value ? 'Tencent' : hk ? '騰訊控股' : '腾讯控股'
- } | HK$163.20 | HK$163.40 | +0.1% | +$12 |
- | 9988.HK | ${
- isEN.value ? 'Alibaba' : '阿里巴巴'
- } | HK$136.80 | HK$123.20 | -9.7% | -$1,736 |
-
-
-${portfolioPieSvg(cn, hk)}
-
${isEN.value ? 'March Summary' : hk ? '3 月小結' : '3 月小结'}:${
- isEN.value
- ? 'AAPL (−5.7%, −$2,003) and 9988.HK (−9.7%, −$1,736) were the biggest drags — combined -$3,739, 87% of total loss. 9618.HK (+5.8%) was the only positive contributor. Portfolio is US-heavy (~78%). HK (~22%) is split: JD strong, Alibaba weak.'
- : hk
- ? 'AAPL(-5.7%,-$2,003)和 9988.HK(-9.7%,-$1,736)是本月最大拖累,合計貢獻 -$3,739,佔總虧損的 87%。9618.HK(+5.8%)是唯一正收益標的。組合美股比例偏高(約 78%),港股(約 22%)表現分化:京東強、阿里弱。'
- : 'AAPL(-5.7%,-$2,003)和 9988.HK(-9.7%,-$1,736)是本月最大拖累,合计贡献 -$3,739,占总亏损的 87%。9618.HK(+5.8%)是唯一正收益标的。组合美股比例偏高(约 78%),港股(约 22%)表现分化:京东强、阿里弱。'
- }
`,
- },
- ],
- clientMessages: {
- claude: [
- {
- role: 'user',
- content: isEN.value
- ? 'Review my portfolio this month: total P&L trend, top contributor, worst performer, US vs HK allocation?'
- : isHK.value
- ? '幫我複盤這個月的持倉表現:總盈虧趨勢如何,哪隻股票貢獻最大、哪隻表現最弱,組合裡美股和港股各佔多少?'
- : '帮我复盘这个月的持仓表现:总盈亏趋势如何,哪只股票贡献最大、哪只表现最弱,组合里美股和港股各占多少?',
- },
- {
- role: 'tool',
- command: 'longbridge positions && longbridge profit --from 2026-03-01 --to 2026-03-24',
- content: '',
- },
- {
- role: 'assistant',
- rich: true,
- content: `
${
- isEN.value
- ? "I pulled your portfolio data from March 1–24. Here's the full review:"
- : hk
- ? '我調取了你 3 月 1 日到 3 月 24 日的持倉數據,以下是完整復盤:'
- : '我调取了你 3 月 1 日到 3 月 24 日的持仓数据,以下是完整复盘:'
- }
-
① ${
- isEN.value ? 'Total P&L' : hk ? '總盈虧' : '总盈亏'
- }
-
${
- isEN.value
- ? 'March portfolio down -$4,287 (−4.8%), underperforming S&P 500 by ~1.2pp. Losses concentrated in mid-to-late month (3/10–3/20), coinciding with the broad tech selloff.'
- : hk
- ? '3 月組合整體下跌 -$4,287(-4.8%),跑輸同期標普 500 約 1.2 個百分點。虧損主要集中在月中下旬(3/10–3/20),與美股科技股整體回調時間一致。'
- : '3 月组合整体下跌 -$4,287(-4.8%),跑输同期标普 500 约 1.2 个百分点。亏损主要集中在月中下旬(3/10–3/20),与美股科技股整体回调时间一致。'
- }
-
② ${
- isEN.value ? 'Contribution Breakdown' : hk ? '貢獻拆解' : '贡献拆解'
- }
-
${
- isEN.value
- ? 'Biggest drags: AAPL (−$2,003) + 9988.HK (−$1,736) = 87% of losses. AAPL is largest position (~38% weight). 9618.HK was the sole positive contributor (+$412), bucking the trend.'
- : hk
- ? '最大拖累:AAPL (-$2,003) + 9988.HK (-$1,736),合計 87% 虧損來源。AAPL 倉位最重(約 38% 組合權重),是主要風險敞口。9618.HK 是唯一正貢獻(+$412),表現逆勢。'
- : '最大拖累:AAPL (-$2,003) + 9988.HK (-$1,736),合计 87% 亏损来源。AAPL 仓位最重(约 38% 组合权重),是主要风险敞口。9618.HK 是唯一正贡献(+$412),表现逆势。'
- }
-
③ ${
- isEN.value ? 'Market Allocation' : hk ? '市場分佈' : '市场分布'
- }
-
${
- isEN.value
- ? 'US stocks ~78% (AAPL 38% + NVDA 20% + MSFT 20%), HK ~22% (9988, 700, 9618). Heavy US tech concentration amplified the drawdown during the correction.'
- : hk
- ? '美股約佔 78%(AAPL 38% + NVDA 20% + MSFT 20%),港股約 22%(9988、700、9618)。集中在美股科技,在科技回調期間放大了下行幅度。'
- : '美股约占 78%(AAPL 38% + NVDA 20% + MSFT 20%),港股约 22%(9988、700、9618)。集中在美股科技,在科技回调期间放大了下行幅度。'
- }
-
${
- isEN.value
- ? 'Period: 2026-03-01 → 2026-03-24 · includes HKD/USD conversion'
- : hk
- ? '數據區間:2026-03-01 → 2026-03-24 · 含 HKD/USD 匯率折算'
- : '数据区间:2026-03-01 → 2026-03-24 · 含 HKD/USD 汇率折算'
- }
`,
- },
- ],
- 'claude-code': [
- {
- role: 'user',
- content: isEN.value
- ? 'Monthly portfolio review: P&L by position, allocation breakdown'
- : isHK.value
- ? '月度持倉複盤:各標的盈虧、倉位分佈'
- : '月度持仓复盘:各标的盈亏、仓位分布',
- },
- {
- role: 'tool',
- command: 'longbridge positions && longbridge profit --from 2026-03-01 --to 2026-03-24',
- content: '',
- },
- {
- role: 'assistant',
- rich: true,
- content: hk
- ? termHTML(`
$ longbridge profit --from 2026-03-01 --to 2026-03-24
-
-
持倉複盤 · 2026-03-01 → 03-24
-
──────────────────────────────────────────────────────
-
Symbol 月初價 當前價 MTD% 貢獻$
-
──────────────────────────────────────────────────────
-
9618.HK HK$101.30 HK$107.20
+5.8% +$412
-700.HK HK$163.20 HK$163.40
+0.1% +$12
-NVDA.US $182.48 $175.64
-4.1% -$691
-MSFT.US $398.55 $379.85
-4.7% -$281
-AAPL.US $264.72 $249.66
-5.7% -$2,003
-
9988.HK HK$136.80 HK$123.20
-9.7% -$1,736
-
──────────────────────────────────────────────────────
-3月總盈虧:
-$4,287 (-4.8%)
-
-倉位分佈: 美股
~78% (AAPL 38%, NVDA 20%, MSFT 20%)
- 港股
~22% (9988, 700, 9618)
-
# AAPL + 9988.HK 貢獻 87% 虧損,建議審視集中度風險`)
- : termHTML(`
$ longbridge profit --from 2026-03-01 --to 2026-03-24
-
-
持仓复盘 · 2026-03-01 → 03-24
-
──────────────────────────────────────────────────────
-
Symbol 月初价 当前价 MTD% 贡献$
-
──────────────────────────────────────────────────────
-
9618.HK HK$101.30 HK$107.20
+5.8% +$412
-700.HK HK$163.20 HK$163.40
+0.1% +$12
-NVDA.US $182.48 $175.64
-4.1% -$691
-MSFT.US $398.55 $379.85
-4.7% -$281
-AAPL.US $264.72 $249.66
-5.7% -$2,003
-
9988.HK HK$136.80 HK$123.20
-9.7% -$1,736
-
──────────────────────────────────────────────────────
-3月总盈亏:
-$4,287 (-4.8%)
-
-仓位分布: 美股
~78% (AAPL 38%, NVDA 20%, MSFT 20%)
- 港股
~22% (9988, 700, 9618)
-
# AAPL + 9988.HK 贡献 87% 亏损,建议审视集中度风险`),
- },
- ],
- },
- },
- ]
-})
-
-interface Client {
- id: string
- label: string
- color: string
-}
-
-// ─── Capability groups ────────────────────────────────────────────────────────
-
-interface CapabilityItem {
- desc: string
-}
-interface CapabilityGroup {
- iconSvg: string
- color: string
- label: string
- items: CapabilityItem[]
-}
-
-const capIcons: Record
= {
- trending: ``,
- barChart: ``,
- users: ``,
- calendar: ``,
- fileText: ``,
- layers: ``,
- briefcase: ``,
- zap: ``,
-}
-
-const capabilityGroups = computed(() =>
- isEN.value
- ? [
- {
- iconSvg: capIcons.trending,
- color: '#00b8b8',
- label: 'Real-time Market Data',
- items: [
- { desc: 'Live quotes for one or more symbols' },
- { desc: 'Level 2 order book depth (bid/ask ladder)' },
- { desc: 'Tick-by-tick recent trades' },
- { desc: 'Intraday minute-by-minute price & volume' },
- { desc: 'OHLCV candlesticks & historical date-range data' },
- { desc: 'Intraday capital flow & distribution' },
- { desc: 'Market sentiment temperature index (0–100)' },
- { desc: 'Static reference info (lot size, shares, EPS…)' },
- { desc: 'Option quotes & option chain' },
- { desc: 'Warrant quotes & warrants by underlying' },
- ],
- },
- {
- iconSvg: capIcons.barChart,
- color: '#4781ff',
- label: 'Fundamentals & Research',
- items: [
- { desc: 'Income statement, balance sheet, cash flow' },
- { desc: 'P/E, P/B, P/S, dividend yield + peer comparison' },
- { desc: 'Analyst EPS forecasts' },
- { desc: 'Revenue & profit consensus with beat/miss' },
- { desc: 'Institution ratings & target price distribution' },
- { desc: 'Calculated financial indexes (PE, PB, DPS rate…)' },
- { desc: 'Institutional shareholders with position changes' },
- { desc: 'Funds & ETFs that hold a given symbol' },
- { desc: 'Dividend history & distribution details' },
- { desc: 'SEC / regulatory filings with full Markdown content' },
- ],
- },
- {
- iconSvg: capIcons.calendar,
- color: '#8b5cf6',
- label: 'Calendar & Events',
- items: [
- { desc: 'Upcoming earnings events by symbol' },
- { desc: 'High-importance macro data events' },
- { desc: 'Upcoming dividend events by market' },
- { desc: 'Trading session schedule & holiday calendar' },
- ],
- },
- {
- iconSvg: capIcons.fileText,
- color: '#f59e0b',
- label: 'News, Community & Watchlist',
- items: [
- { desc: 'Latest news articles for a symbol' },
- { desc: 'Community discussion topics' },
- { desc: 'Watchlist groups: list, create, update, delete' },
- ],
- },
- {
- iconSvg: capIcons.briefcase,
- color: '#6366f1',
- label: 'Account & Portfolio',
- items: [
- { desc: 'Stock positions across all sub-accounts' },
- { desc: 'Fund positions across all sub-accounts' },
- { desc: 'Account cash balance & financing info' },
- { desc: 'Cash flow records (deposits, withdrawals, dividends)' },
- { desc: 'Account statements (daily / monthly)' },
- { desc: 'Exchange rates for all supported currencies' },
- ],
- },
- {
- iconSvg: capIcons.zap,
- color: '#ef4444',
- label: 'Trading',
- items: [
- { desc: 'Limit, market, or stop-limit orders' },
- { desc: "List today's orders, view detail, executions" },
- { desc: 'Cancel a pending order' },
- { desc: 'Modify quantity or price of a pending order' },
- { desc: 'Estimate max buy/sell quantity' },
- { desc: 'Margin ratio requirements for a symbol' },
- ],
- },
- ]
- : [
- {
- iconSvg: capIcons.trending,
- color: '#00b8b8',
- label: isHK.value ? '實時行情' : '实时行情',
- items: [
- { desc: isHK.value ? '一個或多個標的實時報價' : '一个或多个标的实时报价' },
- { desc: isHK.value ? 'Level 2 盤口深度(買賣盤階梯)' : 'Level 2 盘口深度(买卖盘阶梯)' },
- { desc: isHK.value ? '逐筆成交記錄' : '逐笔成交记录' },
- { desc: isHK.value ? '盤中分鐘線價格與成交量' : '盘中分钟线价格与成交量' },
- { desc: isHK.value ? 'K 線 / 歷史區間 OHLCV 數據' : 'K 线 / 历史区间 OHLCV 数据' },
- { desc: isHK.value ? '盤中資金流向與分布' : '盘中资金流向与分布' },
- { desc: isHK.value ? '市場情緒溫度指數(0–100)' : '市场情绪温度指数(0–100)' },
- { desc: isHK.value ? '靜態參考信息(手數、股本、EPS…)' : '静态参考信息(手数、股本、EPS…)' },
- { desc: isHK.value ? '期權報價與期權鏈' : '期权报价与期权链' },
- { desc: isHK.value ? '權證報價及掛鉤標的的權證列表' : '权证报价及挂钩标的的权证列表' },
- ],
- },
- {
- iconSvg: capIcons.barChart,
- color: '#4781ff',
- label: isHK.value ? '基本面研究' : '基本面研究',
- items: [
- {
- desc: isHK.value
- ? '財務三表(收入表、資產負債表、現金流量表)'
- : '财务三表(收入表、资产负债表、现金流量表)',
- },
- { desc: isHK.value ? 'PE/PB/PS、股息率 + 同行估值對比' : 'PE/PB/PS、股息率 + 同行估值对比' },
- { desc: isHK.value ? '分析師 EPS 預測' : '分析师 EPS 预测' },
- {
- desc: isHK.value
- ? '營收與利潤一致性預期(含超預期/不及預期標注)'
- : '营收与利润一致性预期(含超预期/不及预期标注)',
- },
- { desc: isHK.value ? '機構評級與目標價分布' : '机构评级与目标价分布' },
- { desc: isHK.value ? '計算財務指標(PE、PB、股息率…)' : '计算财务指标(PE、PB、股息率…)' },
- { desc: isHK.value ? '機構持股及變動追蹤' : '机构持股及变动追踪' },
- { desc: isHK.value ? '持有某標的的基金與 ETF' : '持有某标的的基金与 ETF' },
- { desc: isHK.value ? '股息歷史與派息詳情' : '股息历史与派息详情' },
- { desc: isHK.value ? 'SEC / 監管申報原文(完整 Markdown)' : 'SEC / 监管申报原文(完整 Markdown)' },
- ],
- },
- {
- iconSvg: capIcons.calendar,
- color: '#8b5cf6',
- label: isHK.value ? '日曆與事件' : '日历与事件',
- items: [
- { desc: isHK.value ? '個股財報日曆' : '个股财报日历' },
- { desc: isHK.value ? '高重要性宏觀數據事件' : '高重要性宏观数据事件' },
- { desc: isHK.value ? '按市場的即將派息事件' : '按市场的即将派息事件' },
- { desc: isHK.value ? '交易時段安排與假期日曆' : '交易时段安排与假期日历' },
- ],
- },
- {
- iconSvg: capIcons.fileText,
- color: '#f59e0b',
- label: isHK.value ? '新聞、社區與自選' : '新闻、社区与自选',
- items: [
- { desc: isHK.value ? '個股最新新聞資訊' : '个股最新新闻资讯' },
- { desc: isHK.value ? '社區話題討論' : '社区话题讨论' },
- { desc: isHK.value ? '自選股管理(查詢、新增、更新、刪除)' : '自选股管理(查询、新增、更新、删除)' },
- ],
- },
- {
- iconSvg: capIcons.briefcase,
- color: '#6366f1',
- label: isHK.value ? '賬戶與持倉' : '账户与持仓',
- items: [
- { desc: isHK.value ? '全子賬戶股票持倉' : '全子账户股票持仓' },
- { desc: isHK.value ? '全子賬戶基金持倉' : '全子账户基金持仓' },
- { desc: isHK.value ? '賬戶現金餘額與融資信息' : '账户现金余额与融资信息' },
- { desc: isHK.value ? '資金流水(入金、出金、股息)' : '资金流水(入金、出金、股息)' },
- { desc: isHK.value ? '賬戶對賬單(日報 / 月報)' : '账户对账单(日报 / 月报)' },
- { desc: isHK.value ? '各幣種匯率' : '各币种汇率' },
- ],
- },
- {
- iconSvg: capIcons.zap,
- color: '#ef4444',
- label: isHK.value ? '交易執行' : '交易执行',
- items: [
- { desc: isHK.value ? '限價、市價、止損限價下單' : '限价、市价、止损限价下单' },
- { desc: isHK.value ? '訂單列表、詳情、成交記錄' : '订单列表、详情、成交记录' },
- { desc: isHK.value ? '撤銷待成交訂單' : '撤销待成交订单' },
- { desc: isHK.value ? '修改訂單數量或價格' : '修改订单数量或价格' },
- { desc: isHK.value ? '最大可買賣數量估算' : '最大可买卖数量估算' },
- { desc: isHK.value ? '標的保證金比例' : '标的保证金比例' },
- ],
- },
- ]
-)
-
-// SVG icons for each client (Simple Icons paths, viewBox="0 0 24 24")
-const clientIcons: Record = {
- openclaw: ``,
- chatgpt: ``,
- claude: ``,
- 'claude-code': ``,
- codex: ``,
-}
-
-// All clients shown in hero chip row (popularity order)
-const heroClients: Client[] = [
- { id: 'openclaw', label: 'OpenClaw', color: '#f59e0b' },
- { id: 'chatgpt', label: 'ChatGPT', color: '#10b981' },
- { id: 'claude', label: 'Claude', color: '#f97316' },
- { id: 'claude-code', label: 'Claude Code', color: '#818cf8' },
- { id: 'codex', label: 'Codex', color: '#94a3b8' },
-]
-
-// Clients available in demo tabs
-const clients: Client[] = [
- { id: 'openclaw', label: 'OpenClaw', color: '#f59e0b' },
- { id: 'chatgpt', label: 'ChatGPT', color: '#10b981' },
- { id: 'claude', label: 'Claude', color: '#f97316' },
- { id: 'claude-code', label: 'Claude Code', color: '#818cf8' },
-]
-
-// ─── Demo animation state ─────────────────────────────────────────────────────
-
-const activeScenario = ref('monitor')
-const activeClient = ref('openclaw')
-
-// Visible messages for the chat window (built up by animation)
-const phase = ref<'idle' | 'user' | 'tool' | 'assistant'>('idle')
-const isRichResponse = ref(false)
-const visibleUserMsg = ref('')
-const visibleToolCmd = ref('')
-const visibleAssistantMsg = ref('')
-const toolExpanded = ref(false)
-
-let animTimer: ReturnType | null = null
-
-function clearAnim() {
- if (animTimer) clearTimeout(animTimer)
- animTimer = null
- phase.value = 'idle'
- isRichResponse.value = false
- visibleUserMsg.value = ''
- visibleToolCmd.value = ''
- visibleAssistantMsg.value = ''
- toolExpanded.value = false
-}
-
-function delay(ms: number): Promise {
- return new Promise((resolve) => {
- animTimer = setTimeout(resolve, ms)
- })
-}
-
-async function typewrite(target: { value: string }, text: string, speed = 5) {
- for (let i = 0; i < text.length; i++) {
- if (phase.value === 'idle') return // aborted
- target.value = text.slice(0, i + 1)
- await delay(speed)
- }
-}
-
-async function runAnimation() {
- clearAnim()
- const msgs = currentMessages.value
- if (!msgs.length) return
-
- const [userMsg, toolMsg, assistantMsg] = msgs
-
- await delay(50)
-
- // Phase 1: user message appears
- phase.value = 'user'
- await typewrite(visibleUserMsg, userMsg.content, 8)
-
- await delay(100)
-
- // Phase 2: tool call appears
- phase.value = 'tool'
- toolExpanded.value = true
- await typewrite(visibleToolCmd, toolMsg.command ?? '', 5)
- await delay(150)
- toolExpanded.value = false
-
- await delay(60)
-
- // Phase 3: assistant response
- isRichResponse.value = !!assistantMsg.rich
- phase.value = 'assistant'
- if (assistantMsg.rich) {
- // Rich HTML content: show at once (fade-in via CSS)
- visibleAssistantMsg.value = assistantMsg.content
- } else {
- await typewrite(visibleAssistantMsg, assistantMsg.content, 10)
- }
-}
-
-watch([activeScenario, activeClient], () => {
- clearAnim()
- phase.value = 'idle'
- runAnimation()
-})
-
-onMounted(() => {
- runAnimation()
-})
-
-onUnmounted(() => {
- clearAnim()
-})
-
-// ─── Copy button ──────────────────────────────────────────────────────────────
-
-const npxCommand = 'npx skills add longbridge/skills -g'
-const openclawCommand = '/skills add longbridge/skills'
-import { siteHostname } from '../utils/region'
-const oneLinerCommand = computed(() =>
- isEN.value
- ? `Install Longbridge AI toolkit following the guide: \n${siteHostname}/skill/install.md`
- : isHK.value
- ? `根據指引安裝 Longbridge AI toolkit:\n${siteHostname}/skill/install.md`
- : `根据指引安装 Longbridge AI toolkit:\n${siteHostname}/skill/install.md`
-)
-
-const copiedNpx = ref(false)
-const copiedOpenclaw = ref(false)
-const copiedOneLiner = ref(false)
-
-async function copyText(text: string, indicator: { value: boolean }) {
- await navigator.clipboard.writeText(text)
- indicator.value = true
- setTimeout(() => (indicator.value = false), 1500)
-}
-
-const copyOneLiner = () => copyText(oneLinerCommand.value, copiedOneLiner)
-const copyNpxCmd = () => copyText(npxCommand, copiedNpx)
-
-// ─── Skills Catalog ───────────────────────────────────────────────────────────
-
-import type { SkillEntry } from './skill-catalog/types'
-
-type CatalogSkill = SkillEntry & { tag?: string }
-
-const catalogLocale = computed(() => (isEN.value ? enLocale : isHK.value ? zhHKLocale : zhCNLocale))
-
-const CATALOG_SKILLS = computed(() =>
- catalogLocale.value.skills.map((s) => ({
- ...s,
- tag: s.tagType ? catalogLocale.value.ui.tagLabels[s.tagType] : undefined,
- }))
-)
-
-const CATALOG_CATS = computed(() =>
- Object.entries(catalogLocale.value.ui.catLabels).map(([id, label]) => ({ id, label }))
-)
-
-const activeCatalogCat = ref('all')
-const catalogQuery = ref('')
-const copiedPluginCmd1 = ref(false)
-function copyPluginCmd1() {
- navigator.clipboard?.writeText('/plugin marketplace add longbridge/skills\n/plugin install longbridge@longbridge-skills')
- copiedPluginCmd1.value = true
- setTimeout(() => (copiedPluginCmd1.value = false), 1400)
-}
-const catalogExpanded = ref(false)
-const openCatalogSkill = ref(null)
-const catalogCols = ref(3)
-const installClient = ref('cli')
-const modalCopiedKey = ref(null)
-
-const _SVG_COMMON = 'width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#00b8b8" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"'
-const CAT_ICONS: Record = {
- meta: ``,
- quote: ``,
- research: ``,
- derivative: ``,
- discovery: ``,
- trade: ``,
- portfolio: ``,
-}
-
-function handleModalCopy(text: string, key: string) {
- navigator.clipboard?.writeText(text)
- modalCopiedKey.value = key
- setTimeout(() => {
- modalCopiedKey.value = null
- }, 1400)
-}
-
-const INSTALL_CLIENTS = computed(() => {
- const pkg = openCatalogSkill.value?.pkg ?? ''
- return {
- cli: {
- label: 'CLI',
- cmd: `npx skills add longbridge/skills -g --skill ${pkg}`,
- uninstall: `npx skills remove ${pkg} -g`,
- upgrade: `npx skills update ${pkg} -g`,
- verify: `npx skills list | grep ${pkg}`,
- },
- claude: {
- label: 'Claude Code',
- cmd: `claude skill add longbridge/skills -g --skill ${pkg}`,
- uninstall: `claude skill remove ${pkg} -g`,
- upgrade: `claude skill update ${pkg} -g`,
- verify: `claude skill list | grep ${pkg}`,
- },
- cursor: {
- label: 'Cursor',
- cmd: `cursor skill add longbridge/skills -g --skill ${pkg}`,
- uninstall: `cursor skill remove ${pkg} -g`,
- upgrade: `cursor skill update ${pkg} -g`,
- verify: `cursor skill list | grep ${pkg}`,
- },
- codex: {
- label: 'Codex',
- cmd: `codex skill add longbridge/skills -g --skill ${pkg}`,
- uninstall: `codex skill remove ${pkg} -g`,
- upgrade: `codex skill update ${pkg} -g`,
- verify: `codex skill list | grep ${pkg}`,
- },
- zed: {
- label: 'Zed',
- cmd: `zed skill add longbridge/skills -g --skill ${pkg}`,
- uninstall: `zed skill remove ${pkg} -g`,
- upgrade: `zed skill update ${pkg} -g`,
- verify: `zed skill list | grep ${pkg}`,
- },
- manual: {
- label: isEN.value ? 'Manual' : '手动安装',
- cmd: `# 1. Download ZIP\ncurl -LO https://open.longbridge.com/skill/${pkg}.zip\n# 2. Extract\nunzip ${pkg}.zip -d ~/.claude/skills/\n# 3. Restart AI client`,
- uninstall: `rm -rf ~/.claude/skills/${pkg}/`,
- upgrade: `curl -LO https://open.longbridge.com/skill/${pkg}.zip\nunzip -o ${pkg}.zip -d ~/.claude/skills/`,
- verify: `ls ~/.claude/skills/${pkg}/`,
- },
- } as Record
-})
-
-const tabsEl = ref(null)
-const indicatorStyle = ref({ left: '0px', width: '0px' })
-function updateIndicator() {
- if (!tabsEl.value) return
- const active = tabsEl.value.querySelector('.sc-tab--active')
- if (!active) return
- const base = tabsEl.value.getBoundingClientRect()
- const rect = active.getBoundingClientRect()
- indicatorStyle.value = { left: rect.left - base.left + 'px', width: rect.width + 'px' }
- const wrap = tabsEl.value.parentElement
- if (wrap) {
- const targetScroll = active.offsetLeft - wrap.clientWidth / 2 + active.offsetWidth / 2
- wrap.scrollTo({ left: targetScroll, behavior: 'smooth' })
- }
-}
-watch(activeCatalogCat, () => nextTick(updateIndicator))
-
-function updateCatalogCols() {
- if (typeof window === 'undefined') return
- const w = window.innerWidth
- catalogCols.value = w <= 600 ? 1 : w <= 960 ? 2 : 3
-}
-
-function onModalKey(e: KeyboardEvent) {
- if (e.key === 'Escape') openCatalogSkill.value = null
-}
-onMounted(() => {
- updateCatalogCols()
- window.addEventListener('resize', updateCatalogCols)
- window.addEventListener('keydown', onModalKey)
- nextTick(updateIndicator)
-})
-onUnmounted(() => {
- window.removeEventListener('resize', updateCatalogCols)
- window.removeEventListener('keydown', onModalKey)
-})
-
-watch([activeCatalogCat, catalogQuery], () => {
- catalogExpanded.value = false
-})
-watch(openCatalogSkill, () => {
- installClient.value = 'cli'
- modalCopiedKey.value = null
-})
-
-const filteredCatalogSkills = computed(() => {
- const q = catalogQuery.value.trim().toLowerCase()
- return CATALOG_SKILLS.value.filter((s) => {
- if (q) return (s.pkg + ' ' + s.name + ' ' + s.desc).toLowerCase().includes(q)
- return activeCatalogCat.value === 'all' || s.cat === activeCatalogCat.value
- })
-})
-
-const catalogCap = computed(() => catalogCols.value * 3)
-
-const shownCatalogSkills = computed(() =>
- catalogExpanded.value || filteredCatalogSkills.value.length <= catalogCap.value
- ? filteredCatalogSkills.value
- : filteredCatalogSkills.value.slice(0, catalogCap.value)
-)
-
-const catalogCounts = computed(() =>
- Object.fromEntries(
- CATALOG_CATS.value.map((c) => [
- c.id,
- c.id === 'all' ? CATALOG_SKILLS.value.length : CATALOG_SKILLS.value.filter((s) => s.cat === c.id).length,
- ])
- )
-)
-
-
-function triggerRipple(event: MouseEvent, el: HTMLElement) {
- const ripple = el.querySelector('.sc-ripple')
- if (!ripple) return
- const r = el.getBoundingClientRect()
- const x = event.clientX - r.left
- const y = event.clientY - r.top
- ripple.style.left = x + 'px'
- ripple.style.top = y + 'px'
- ripple.getAnimations().forEach((a) => a.cancel())
- ripple.animate(
- [
- { width: '0px', height: '0px', opacity: 0.6 },
- { width: '600px', height: '600px', opacity: 0 },
- ],
- { duration: 400, easing: 'ease-out', fill: 'forwards' }
- )
-}
-
-// ─── Helpers ──────────────────────────────────────────────────────────────────
-
-const currentClient = computed(() => clients.find((c) => c.id === activeClient.value) ?? clients[0])
-
-const currentMessages = computed(() => {
- const scenario = demoScenarios.value.find((s) => s.id === activeScenario.value)
- if (!scenario) return []
- return scenario.clientMessages?.[activeClient.value] ?? scenario.messages
-})
-
-const currentScenarioCard = computed(
- () => scenarioCards.value.find((c) => c.id === activeScenario.value) ?? scenarioCards.value[0]
-)
-
-const currentExample = computed(() => {
- const card = currentScenarioCard.value
- if (activeClient.value === 'claude-code' && card.claudeCodeExample) {
- return card.claudeCodeExample
- }
- return card.example
-})
-
-
-
-
-
+
+
+
+
+
+
+ Get started
+
Choose your AI tool
+
+
+
+
+
Copy and send to any AI
+
+ Paste this message into any AI assistant (Claude, ChatGPT, Cursor) and it will guide you through the
+ installation.
+
+
+
{{ installCmd }}
+
+
+
-
-
-
{{ t.ctaHint.value }}
-
-
-
-
-
{{ t.supportedBy.value }}
-
-
-
- {{ c.label }}
-
-
- {{ isEN ? 'Cursor, Zed, and more...' : 'Cursor, Zed, 更多...' }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{ currentScenarioCard.title }}
-
{{ currentScenarioCard.desc }}
-
-
-
{{ isEN ? 'Try asking' : isHK ? '試試這樣問' : '试试这样问' }}
-
-
-
{{ currentExample }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
{{ currentClient.label }}
-
-
-
-
-
-
-
- {{ visibleUserMsg }}
-
-
-
-
-
-
-
-
-
-
-
-
-
{{ visibleAssistantMsg }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ catalogLocale.ui.noResults(catalogQuery) }}
- 。
+
+
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
{{ openCatalogSkill.name }}
-
- {{ openCatalogSkill.pkg }}
- ·
- {{ catalogLocale.ui.catLabels[openCatalogSkill.cat] }}
- ·
- {{ openCatalogSkill.tools }} {{ isEN ? 'tools' : isHK ? '個工具' : '个工具' }}
-
-
-
-
{{ openCatalogSkill.desc }}
-
-
+
diff --git a/docs/.vitepress/theme/components/index.ts b/docs/.vitepress/theme/components/index.ts
index 05679cd9..30ada383 100644
--- a/docs/.vitepress/theme/components/index.ts
+++ b/docs/.vitepress/theme/components/index.ts
@@ -1,3 +1,5 @@
+export { default as AppNav } from './AppNav.vue'
+export { default as AppFooter } from './AppFooter.vue'
export { default as CliCommand } from './CliCommand.vue'
export { default as FeaturesMenu } from './FeaturesMenu.vue'
export { default as Tabs } from './Tabs.vue'
@@ -7,7 +9,6 @@ export { default as SDKLinks } from './SDKLinks.vue'
export { default as SDK } from './SDK.vue'
export { default as Skill } from './Skill.vue'
export { default as TryIt } from './TryIt/index.vue'
-export { default as HomePage } from './HomePage/index.vue'
export { default as NewHomePage } from './NewHomePage/index.vue'
export { default as McpTools } from './McpTools.vue'
export { default as QuantChart } from './QuantChart.vue'
diff --git a/docs/.vitepress/theme/composables/index.ts b/docs/.vitepress/theme/composables/index.ts
index c0421df5..f180e869 100644
--- a/docs/.vitepress/theme/composables/index.ts
+++ b/docs/.vitepress/theme/composables/index.ts
@@ -1,4 +1,5 @@
export { useThemeToggle } from './useThemeToggle'
+export { useLbDarkSync } from './useLbDarkSync'
export { isLoginState, initLoginState, toggleMockLogin } from './useLoginState'
export { useI18nSync } from './useI18nSync'
export { useHighlighter } from './useHighlighter'
diff --git a/docs/.vitepress/theme/composables/useLbDarkSync.ts b/docs/.vitepress/theme/composables/useLbDarkSync.ts
new file mode 100644
index 00000000..53c5f325
--- /dev/null
+++ b/docs/.vitepress/theme/composables/useLbDarkSync.ts
@@ -0,0 +1,9 @@
+import { watch } from 'vue'
+import { useData } from 'vitepress'
+
+export function useLbDarkSync() {
+ const { isDark } = useData()
+ watch(isDark, (dark) => {
+ document.documentElement.classList.toggle('lb-dark', dark)
+ }, { immediate: true })
+}
diff --git a/docs/.vitepress/theme/layouts/Content.vue b/docs/.vitepress/theme/layouts/Content.vue
index 3ec050a3..4c5ae9e7 100644
--- a/docs/.vitepress/theme/layouts/Content.vue
+++ b/docs/.vitepress/theme/layouts/Content.vue
@@ -28,10 +28,6 @@ const { isHome, hasSidebar } = useLayout()
}
@media (min-width: 960px) {
- .VPContent {
- padding-top: var(--vp-nav-height);
- }
-
.VPContent.has-sidebar {
margin: var(--vp-layout-top-height, 0px) 0 0;
padding-left: var(--vp-sidebar-width);
diff --git a/docs/.vitepress/theme/layouts/Layout.vue b/docs/.vitepress/theme/layouts/Layout.vue
index 72c7eb00..441506df 100644
--- a/docs/.vitepress/theme/layouts/Layout.vue
+++ b/docs/.vitepress/theme/layouts/Layout.vue
@@ -1,26 +1,20 @@
-
-
-
-
@@ -40,21 +34,6 @@ const { llmMarkdownLink } = useLLMMarkdownLink()