Commit Graph

41 Commits

Author SHA1 Message Date
zhulinsen
03dd26ac2e ci: shard backend tests across runners (#2165) 2026-08-05 22:33:50 +08:00
zhulinsen
8052d1a0ac ci: accelerate selective test gates (#2158) 2026-08-05 19:14:40 +08:00
zhulinsen
91988da149 feat: 添加报告分享图片与 Web 一键分享 (#2146)
* feat: add report image sharing

* fix(review-feedback-2146): 评审结论 - 代码检查 :当前整个 PR 仍有 2 个未关闭的高置信度代码 blocker。最新复核摘要:基于 merge-base

* fix(review-feedback-2146): preserve the Markdown fallback for unavailable snapshots and preserve

* fix(review-feedback-2146): 补一组通知回归测试,至少覆盖

* fix(review-feedback-2146): 在源码树执行 npm ci 和 npx playwright install chromium,这与预编译 desktop 发行包环境不一致

* fix(review-feedback-2146): 评审结论 - 代码检查 :当前整个 PR 仍有 1 个未关闭的高置信度代码 blocker。最新复核摘要:基于 merge-base

* fix(review-feedback-2146): 补上明确的 CLI/Chromium 安装提示,避免当前日志和 503 文案继续把用户引向

* fix(review-feedback-2146): 补到与 docs/share-images.md 一致,直接提示 cd apps/dsa-web && npm ci 和 npx
2026-08-02 16:45:37 +08:00
Nicholas-Xiong
8d8fa56bc7 ci(#2131): 给 backend-gate offline pytest 加 --timeout=120 + faulthandler_timeout=300 watchdog (#2140)
* ci(#2131): 给 backend-gate offline pytest 加 --timeout=120 + faulthandler_timeout=300

issue #2131 报告 backend-gate 在执行 `Offline test suite` 步骤时两次
在同一提交 `e6abcef17fbc5d655c1c49429182079f02d6552e`(PR #2123)
上间歇性无 traceback 卡住:

  workflow run 30551305640(2026-07-30):
    - Offline test suite 开始于 14:23:13 UTC
    - 最后一条测试输出 14:23:58 UTC(AlphaSift hotspot PASSED [11%])
    - job 在 22 分 38 秒无输出后被取消

  workflow run 30553352307(2026-07-30):同样在 11% 位置卡住

GitHub Actions runner 在被取消前没有 pytest 进度的任何信号,也没
有 traceback。本地 16 个 AlphaSift hotspot 测试都能稳过,意味着
问题是 CI-only 的测试执行顺序、进程级全局状态、线程/事件循环
清理或依赖行为 — 没有稳定的 assertion failure 可调试。

issue #2131 已经列出推荐排查方向之一:给 pytest 加单测试超时与
卡住时的线程栈 dump(`pytest-timeout`、`faulthandler_timeout`)。
但当前 `scripts/ci_gate.sh` 的 `offline_test_suite()` 仅运行
`python -m pytest -m "not network"`,没有任何超时或 watchdog。

本 PR 实施 issue #2131 推荐的 watchdog 改造,目标不是修复根因
(那需要 issue #2131 的等线程栈 dump 复现才能定位),而是让任何
未来 CI hang 都会留下可定位的失败信息或 post-mortem 栈,而不是
静默消亡到 GitHub Actions workflow timeout 才被取消。

改动:

1. `.github/requirements-ci.txt`:新增 `pytest-timeout>=2.3.0`
   依赖。CI 的 `setup-python` + `pip install -r` 步骤会自动拉取。

2. `scripts/ci_gate.sh` 的 `offline_test_suite()`:
     python -m pytest -m "not network" \
       --timeout=120 -o timeout_method=thread \
       -o faulthandler_timeout=300

   - `--timeout=120`:单个测试如果执行超过 2 分钟直接 fail,
     生成 pytest-timeout 的 traceback 指出是哪个 case。
   - `-o timeout_method=thread`:pytest-timeout 用 watcher 线程
     而非 signal 方法,对吞了 SIGINT/SIGTERM 的测试更可靠
     (yfinance、AlphaSift 这类的 Threads/eventloop 都
     有可能 swallow signal)。
   - `-o faulthandler_timeout=300`:pytest 内置 faulthandler
     的 watchdog,整体 pytest 5 分钟无任何输出(最末一个测试
     结束到下一个测试开始之间的「沉默期」超过 300 秒)就 dump
     全部 Python 线程栈到 stderr。这是定位卡住位置的关键信号。

3. `docs/CHANGELOG.md`:在 [Unreleased] 段加一条 [修复] entry
   描述本次改动并指明 issue #2131。

本地验证:

  $ pip install pytest-timeout
  $ bash -n scripts/ci_gate.sh && echo syntax ok
  $ python -m pytest -m "not network" --timeout=120 \
      -o timeout_method=thread -o faulthandler_timeout=300 \
      tests/test_stock_list_parser.py tests/test_stock_code_utils.py -q
  ============================== 98 passed in 2.00s ==============================

  $ flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
  0

行为不变项:

- 本地开发 `python -m pytest ...` 不带 `--timeout` 仍可任意长跑调试
  (`setup.cfg` 没在 `[tool:pytest]` 全局加 timeout — 仅 CI 路径加)。
- `scripts/ci_gate.sh` 的 syntax/flake8/deterministic phases 不受影响。
- `pytest-timeout` 只在 `scripts/ci_gate.sh` 的 offline_test_suite 被
  调用时生效,不会污染本地开发流程。

注:本 PR 不修复 issue #2131 的根本 hang 原因(仍需 thread dump 复
现定位),而是把未来的 hang 转成可定位的失败。reviewer 在 issue
#2131 上对类似方向说过「即使再次复现,定位价值很低」—— 但本 PR
的 watchdog 至少把「无信息消亡」转成「带 stacktrace 的 fail」,
当 hang 再次发生时能立刻看到卡在哪个测试的哪一行。

* ci(#2131): close PR #2140 review blocker OR-COM-cc22d635 + OR-COM-c76d8eff — docker-publish.yml 对齐 backend-gate 依赖安装

按 reviewer 在 head `e01a1835` 上的 OpenReview Bot 复核反馈,关闭以下 2 个
高置信度 compatibility blocker:

- OR-COM-cc22d635: Docker Release Publish workflow 的 Install backend gate
  dependencies 仍按旧依赖集合执行 ./scripts/ci_gate.sh,新加的
  pytest-timeout 没覆盖到发布入口
- OR-COM-c76d8eff: 与 OR-COM-cc22d635 同源,cache-dependency-path 也
  缺失 .github/requirements-ci.txt

## 改了什么

.github/workflows/docker-publish.yml:
- setup-python cache-dependency-path 对齐 ci.yml backend-gate:
  加入 requirements.txt + .github/requirements-ci.txt 两个文件
  作为 pip cache key,命中缓存
- Install backend gate dependencies 改用与 ci.yml 完全相同的
  pattern:retry loop (3 attempts, 15s backoff) + 单一
  pip install -r .github/requirements-ci.txt(该文件已 -r 递归拉
  requirements.txt,所以无需重复 pip install -r requirements.txt)
- 加注释说明 issue #2131 引入 pytest-timeout 的关联

docs/CHANGELOG.md:
- [Unreleased] #2131 entry 末尾补一句:同步修正 docker-publish.yml
  的 install 与 cache-dependency-path 对齐

## 为什么这么改

issue #2131 让 scripts/ci_gate.sh 的 offline_test_suite 用
`--timeout=120 -o timeout_method=thread -o faulthandler_timeout=300`,
这要求 pytest-timeout>=2.3.0 插件。

ci.yml 的 backend-gate 已通过 .github/requirements-ci.txt 安装该
插件,但 docker-publish.yml 仍用旧的 `pip install flake8 pytest`,
没有 pytest-timeout,发布前 gate 跑 ./scripts/ci_gate.sh 会直接
报 unrecognized --timeout=120 fail,阻断镜像发布。

reviewer OR-COM-cc22d635 / OR-COM-c76d8eff 都指这是 PR 引入的
compatibility regression(不是已有旧债),需要 PR 同步修。

ci.yml 的 install pattern 是 retry 3 次带 backoff,对齐到
docker-publish 让两个工作流完全统一,未来新加 CI-only 依赖只需改
.github/requirements-ci.txt。

## 验证情况

已本地验证:
- python -c "import yaml; yaml.safe_load(open('.github/workflows/
  docker-publish.yml'))" — YAML 语法 OK
- 对比 ci.yml 的 backend-gate install 步骤,pattern 完全一致

已 CI 验证(待 push 后跑):
- 本 PR 触发 backend-gate / docker-build / ai-governance / Change
  Detection,但 docker-publish.yml 只在 v*.*.* tag 或 workflow_dispatch
  触发,本 PR CI 不会真跑该 workflow。reviewer 复核时会做静态比对

未验证 / 风险点:
- 真实发布流程跑不通:需要 maintainer 推 v*.*.* tag 或手动
  workflow_dispatch 触发,才能验证发布前 gate 真的工作
- 但 install pattern 与 ci.yml 完全对齐,ci.yml 那边过则该边也
  应该过;问题概率很低

## 风险点与回滚

回滚:
1. revert 本 commit
2. docker-publish.yml install step 改回 pip install -r requirements.txt
   + pip install flake8 pytest
3. cache-dependency-path 删除新增两行
4. CHANGELOG.md entry 末尾去掉补充句

潜在风险:
- .github/requirements-ci.txt 递归 -r requirements.txt,release
  runner 之前装过 requirements.txt;retry loop + cache 应该吸收掉
  任何 pip 网络抖动,但首次 release 可能比之前略慢(多一次冗余
  install)。Trade-off 可接受:与 ci.yml 完全统一比省一次冗余
  install 更重要。

* docs(#2131): 收窄 PR #2140 faulthandler_timeout 措辞 + 补 PR 描述 Refs/回滚

OpenReview Bot 在 head 14416440 上已给「可以直接合入」结论,剩 2 个非阻断建议:
1. CHANGELOG 与 PR 描述里 -o faulthandler_timeout=300 写成「整体超过 5 分钟无输出 watchdog」与 pytest 实际语义不一致,应改为「单个测试(含其 teardown)超过 5 分钟时 dump 线程栈」
2. 把 issue 关联补成显式 Refs #2131 + 加最小回滚方案

本 commit 同步两条:
- docs/CHANGELOG.md:把 faulthandler_timeout 描述从「整体超过 5 分钟无输出时 dump 全部线程栈」改为「单个测试(含其 teardown)超过 5 分钟时 dump 全部线程栈」,与 python -m pytest --help 中 faulthandler_timeout 的语义对齐
- PR #2140 描述:在末尾追加 "## 关联 issue Refs #2131" 与 "## 最小回滚方案" 两段(用 gh pr edit --body-file 更新),按 .github/PULL_REQUEST_TEMPLATE.md 模板完整化

无代码逻辑改动,仅文案同步。

---------

Co-authored-by: xxiaoxiong <xxiaoxiong@nicholasxiong.cn>
2026-08-01 22:41:41 +08:00
zhulinsen
bcb7ae4e13 feat: 将参考 AlphaSift 的选股实现纳入主项目 (#2136)
* feat: integrate built-in stock screening engine

* test: verify screening routes via public contract

* refactor: make screening integration fully native

* fix(review-feedback-2136): [Verification blocker] 当前 Head 的阻断型 CI 已最终失败:backend-gate。请在本地运行对应

* feat: persist screening runs and reuse DSA analysis

* fix(review-feedback-2136): 对选股重排应用统一的模型参数兼容逻辑

* fix(review-feedback-2136): 将字段缺失计入数据源失败

* fix(review-feedback-2136): 评审结论 - 代码检查 :当前整个 PR 仍有 3 个未关闭的高置信度代码 blocker。最新复核摘要:当前整个 PR 仍有 3

* fix(review-feedback-2136): 延迟写入候选直到覆盖率通过校验 and 将 DSA 日线成功结果写入 last-good 缓存

* fix(review-feedback-2136): 将直连日线源纳入统一调用超时 and 将新增的选股缓存目录加入桌面更新备份

* fix(review-feedback-2136): 保留完整热点缓存而非请求切片 and 遵守 DSA 上下文声明的候选上限

* fix(review-feedback-2136): 补一条端到端回归:把真实 ScreenResult 经 ScreeningService.screen 落到 /history 和

* fix(review-feedback-2136): 补一个 refresh=true 且 live fetch 失败时返回 stale cache 的回归测试,避免当前只更新 stale
2026-08-01 14:13:23 +08:00
zhulinsen
2e7f4caaae fix: 避免 macOS unsigned 包携带残缺签名 (#2101)
* fix: mitigate broken signatures in unsigned macOS packages

* fix: normalize app signatures before DMG packaging
2026-07-26 11:40:10 +08:00
JaxonHu
d13721e817 feat: 新增富途Futu真实持仓导入支持 (#2042)
* feat: add Futu portfolio import support

* docs: condense Futu changelog entry

* fix: tighten Futu portfolio import contracts
2026-07-20 22:45:45 +08:00
Alfred
628c5b6ef7 feat: add Codex App Server agent prototype (#2004) 2026-07-19 16:31:54 +08:00
zhulinsen
e8a9ca7742 fix: harden release packages and report market context (#1994)
* fix: bundle orjson in release packages

* fix: remove duplicate decision signal excerpts

* feat: add TickFlow sector ranking fallback
2026-07-12 18:56:21 +08:00
zhulinsen
6fda28b4be fix: bundle AkShare calendar data in desktop builds (#1990) 2026-07-12 14:38:49 +08:00
zhulinsen
ef9371003c feat: harden JP/KR suffix market support (#1817)
* feat: harden JP/KR suffix market support

* fix: define yfinance index quote metadata

* fix(review-feedback-1817): Handle JP 4-digit bare-code lookup in analysis paths

* fix(review-feedback-1817): Route 4-digit JP bases through API normalization

* fix(review-feedback-1817): 补齐外部 API/provider/运行时配置风险说明或证明该检测为误报
2026-06-27 22:10:08 +08:00
mumu
ec6c8fbbcf fix: support JP/KR web autocomplete (#1721) 2026-06-19 13:34:21 +08:00
mumu
e2fe6e3056 fix: verify packaged AlphaSift adapter at runtime (#1637)
* fix: verify packaged AlphaSift adapter at runtime

* fix(review-feedback-1637): Wait for the windowed probe process

* fix(review-feedback-1637): 收敛 docs/CHANGELOG.md 的范围漂移/描述不一致问题

* fix(review-feedback-1637): 收敛 docs/CHANGELOG.md 的无关历史改动,只保留本 PR 对 [Unreleased] 的新增修复条目
2026-06-08 07:21:59 +08:00
Delicious233
3471afbd98 feat: add Feishu App Bot notification sender with P2P and group support (#1553)
* feat: add Feishu App Bot notification sender with P2P and group support

The existing FeishuSender only supports custom robot Webhook mode.
This commit extends it to support App Bot (lark-oapi SDK) mode, auto-routing
between webhook (priority) and App Bot when FEISHU_APP_ID + FEISHU_APP_SECRET
+ FEISHU_CHAT_ID are configured.

Design:
- send_to_feishu() routes: webhook if URL set, else App Bot
- DCLP lazy client init with thread-safe sentinel guard
- Retry (3 attempts, exponential backoff) with fixed UUID for idempotency
- Card-first / text-fallback content strategy
- Chunking for long messages
- Runtime enum validation for FEISHU_RECEIVE_ID_TYPE and FEISHU_DOMAIN
- Safe SDK defaults (FEISHU_DOMAIN/LARK_DOMAIN) before import try-block
  so Webhook path never depends on lark-oapi SDK presence
- Config, diagnostics, setup check, notification test, and CI workflow
  all consistent with the new App Bot channel semantics
- lark-oapi>=1.0.0 already in requirements.txt (line 23)

Verification:
- 20/20 unit tests pass (help metadata + FeishuSender)
- E2E: real Feishu API — SDK import, token, client init, P2P text+card send all PASS
- Webhook regression: verified no SDK dependency for existing Webhook path

* fix: add missing Feishu App Bot locale entries and env table keys, harden sender error handling

CI fix 1 (test_registry_help_keys_exist_in_locales):
- Add zh-CN and en-US locale entries for FEISHU_CHAT_ID,
  FEISHU_RECEIVE_ID_TYPE, FEISHU_DOMAIN in settingsHelp.ts

CI fix 2 (test_notification_actions_env_table_matches_generated_output):
- Add FEISHU_RECEIVE_ID_TYPE, FEISHU_DOMAIN to feishu advanced_keys
  in CHANNEL_SPECS so they appear in KEY_SPECS
- Regenerate managed env table in docs/notifications.md

feishu_sender.py hardening:
- Catch network exceptions in webhook _post_payload so card-to-text
  fallback actually executes on transient failures
- Guard response.json() and isinstance(result, dict) against
  non-JSON / non-dict HTTP 200 responses
- Extract shared _build_card_body() to de-duplicate card payload
  construction between webhook and App Bot paths
- Rename module-level lark -> _lark to avoid shadowing
- Guard resp.get_log_id() with try/except
- Add None guard on send_to_feishu content parameter

e2e script improvements:
- Support FEISHU_OPEN_ID for P2P test, FEISHU_DOMAIN for Lark
- Add FEISHU_TEST_SEND_TEXT=1 for plain-text-only path testing
- Clarify docstring: setup validation + smoke test, not full e2e

* fix: consolidate Feishu App Bot notification contract

* fix: align Feishu domain help scope

---------

Co-authored-by: mumu <42829555+ZhuLinsen@users.noreply.github.com>
2026-06-05 08:56:42 +08:00
mumu
0ca4e07b0e feat: integrate AlphaSift with DSA runtime enrichment (#1577)
* feat: integrate AlphaSift with DSA runtime enrichment

* feat: pin AlphaSift DSA provider context

* fix: clean up AlphaSift warning display

* fix(review-feedback-1577): pass the headers through a path AlphaSift actually uses, such as a

* fix(review-feedback-1577): 补齐 LLM 运行时桥接兼容性的关键证据

* fix: keep AlphaSift screening lightweight

* fix(review-feedback-1577): Populate DSA news when reusing context

* fix(review-feedback-1577): 补齐外部 LLM/LiteLLM 兼容依据,并修正 docs/CHANGELOG.md 的格式/重复条目问题

* fix(review-feedback-1577): 补齐外部模型/API 兼容依据或在 PR 正文中明确指向已更新文档中的官方来源与迁移/回退边界

* fix(review-feedback-1577): scripts/build-backend.ps1 已随本 PR 调整 AlphaSift 打包/收集逻辑,但完整改动文件列表未包含

* fix(review-feedback-1577): 处理 AlphaSift LLM bridge 对全局 LiteLLM 状态的并发污染风险

* fix: reuse DSA daily history for AlphaSift

* fix(review-feedback-1577): 补齐 --collect-all alphasift 或等价 hidden imports,并增加打包产物级导入验证

* fix(review-feedback-1577): fix the macOS AlphaSift package verifier

* fix(review-feedback-1577): scripts/build-backend-macos.sh 和 scripts/build-backend.ps1

* fix(review-feedback-1577): 处理运行时阻塞风险、CHANGELOG 删除既有条目,以及补齐外部模型/API 兼容证据

* fix(review-feedback-1577): scripts/build-backend-macos.sh:当前“Verifying packaged AlphaSift

* fix(review-feedback-1577): 收敛下面的可用性判断和外部 API/模型兼容证据缺口

* fix(review-feedback-1577): src/config.py、src/core/config registry.py、src/services/alphasift

* fix(review-feedback-1577): scripts/build-backend-macos.sh:新增的 packaged AlphaSift importability

* fix(review-feedback-1577): make the archive fallback require a dsa adapter entry or exercise the

* fix(review-feedback-1577): 处理无关测试改动,并补齐桌面打包文档/验证边界
2026-06-05 08:53:55 +08:00
mumu
5cd968b411 fix: improve Windows first-run encoding compatibility (#1583) 2026-06-03 22:36:50 +08:00
mumu
72213437f2 feat: add lightweight AlphaSift screening integration (#1443)
* feat: add lightweight AlphaSift screening integration

* fix(review-feedback-1443): 解决冲突后重新确认受影响文件和 CI 结果 and Restrict install spec before executing pip

* fix(review-feedback-1443): add a feature/auth gate before invoking installation side effects

* fix: repair AlphaSift enable flow

* fix(review-feedback-1443): Enable config before calling AlphaSift install

* fix(review-feedback-1443): re-fetch status in the error path to avoid this UI/backend state

* fix(review-feedback-1443): 补充对应回归测试

* fix(review-feedback-1443): 补充对应测试

* fix(review-feedback-1443): api/v1/endpoints/alphasift.py 的状态接口会返回 ALPHASIFT INSTALL SPEC,而项目默认

* fix(review-feedback-1443): 补一个前端用例覆盖

* fix(review-feedback-1443): 解决冲突后再合入

* fix(review-feedback-1443): 解决后再重新确认 diff 与 CI 结果

* fix(review-feedback-1443): 解决冲突并确认解决后的 diff 未引入新风险

* fix(review-feedback-1443): Read picks from AlphaSift ScreenResult and Use AlphaSift's actual

* fix(review-feedback-1443): 修正

* fix(review-feedback-1443): 解决冲突并重新确认 CI/Web gate 结果

* fix(review-feedback-1443): 解决冲突并重新确认 CI/Web gate,另外需要澄清本次 diff 中 LLM 配置相关改动是否属于本 PR 范围及其兼容性影响

* fix(review-feedback-1443): 解决冲突,并补齐受影响前端构建/测试验证后再合入

* fix(review-feedback-1443): 解决冲突,并补齐受影响前端 Web gate 或等价 CI 证据后再合入

* fix(review-feedback-1443): 解决冲突,并补齐受影响 Web gate 与兼容性验证说明后再合入

* fix(review-feedback-1443): mark this field sensitive and/or display only a masked/sanitized source

* fix(review-feedback-1443): 解决冲突,并补齐受影响前端验证与外部兼容性说明后再合入

* fix(review-feedback-1443): 解决冲突,并补齐冲突解决后的验证结果后再合入

* fix(review-feedback-1443): 解决冲突,并补齐受影响后端/Web 验证证据后再合入

* fix(review-feedback-1443): 解决冲突后基于最终 head 重新给出验证结论,否则无法确认最终合入内容与当前审查内容一致

* fix(review-feedback-1443): 解决冲突并补齐冲突后的验证结论

* fix(review-feedback-1443): Clear stale candidates when strategy changes

* fix(review-feedback-1443): preserve TestClient cookies across requests

* fix(review-feedback-1443): 解决冲突并基于冲突后的最终 head 重新确认受影响验证,当前不能直接合入

* fix(review-feedback-1443): 补回归测试

* fix(review-feedback-1443): 补后端回归测试

* fix(review-feedback-1443): 解决冲突,并在解决后重新给出基于最终 head 的验证结果

* fix(review-feedback-1443): 解决冲突并基于最终 diff 重新确认验证结果

* fix(review-feedback-1443): 解决冲突,并在冲突解决后的最终 head 上重新给出后端与 Web 相关验证结论

* fix(review-feedback-1443): 解决冲突,并在最终 head 上重新确认后端、Web 和文档改动仍一致

* fix(review-feedback-1443): 当前 PR 存在合并冲突,虽然 CI 摘要为 success,但冲突解决后的最终代码和验证结果尚未形成,当前不能直接合入

* fix(review-feedback-1443): 解决冲突并补齐验证

* fix(review-feedback-1443): 解决冲突

* fix(review-feedback-1443): 修正测试客户端生命周期问题,并补齐前端 lint/build 验证

* fix(review-feedback-1443): 解决冲突

* feat: refine AlphaSift adapter integration

* fix: restore settings help metadata for CI

* fix(review-feedback-1443): Do not run lifespan for non-context TestClient requests

* fix(review-feedback-1443): Pin AlphaSift install source to an immutable ref

* fix(review-feedback-1443): 补齐后再合入

* fix: harden alphasift review feedback

* fix(review-feedback-1443): api/v1/endpoints/alphasift.py:自动安装路径在 adapter 可导入但 get status 返回

* fix: package alphasift endpoint in desktop build

* fix: bundle alphasift in desktop builds

* fix(review-feedback-1443): docs/alphasift-integration.md 中 AlphaSift adapter contract /

* fix: honor empty alphasift install spec

* fix: bundle alphasift in docker image
2026-05-31 23:12:23 +08:00
mumu
647b9d24e5 fix: support Longbridge OAuth token cache (#1490)
* fix: support Longbridge OAuth token cache

* fix(review-feedback-1490): bump the runtime dependency minimum or fail with a clear upgrade

* fix(review-feedback-1490): 补充对应回归测试

* fix(review-feedback-1490): Point OAuth cache at the dsa home in Docker

* fix(review-feedback-1490): 修复或给出明确的 CI 重跑通过证据

* fix(review-feedback-1490): 处理 Docker/Actions 持久化 token cache 已损坏时无法被新的 LONGBRIDGE OAUTH TOKEN

* fix: tighten Longbridge OAuth compatibility

* fix: refresh stale Longbridge OAuth cache

* fix: guard Longbridge OAuth SDK availability
2026-05-29 23:08:16 +08:00
LouisHong
43d05b4179 feat: Enhance A-share stock name correction and index generation (#1462)
- Improved `fetch_tushare_stock_list.py` to support A-share name corrections for stocks with prefixes XD/XR/DR/N/C using the `--a-rk` option.
- Updated documentation to reflect the new functionality and usage of the correction script.
- Added a new script `refresh_stock_index.py` to automate the fetching of stock lists and index generation.
- Implemented tests for the new features, ensuring the correct functionality of stock name corrections and index generation.
- Enhanced error handling for missing dependencies and improved user feedback during execution.
2026-05-25 20:26:24 +08:00
mumu
f684dc75f4 fix: macOS 桌面端打包缺失 strategies 目录 (#1377)(#1387) 2026-05-21 22:40:08 +08:00
mumu
6684e327dd chore: prioritize daily analysis workflow (#1373) 2026-05-20 22:24:44 +08:00
mumu
4733d2185a fix: unify desktop updater artifacts (#1320) 2026-05-16 17:49:34 +08:00
zhulinsen
71501d6873 fix: disable desktop auto publish during release builds 2026-05-16 15:45:51 +08:00
Alfred
60d8211aa4 docs: close notification issue 1200 (#1276) 2026-05-13 22:04:36 +08:00
mumu
41844a181d feat: add desktop auto-update install flow (#1256) 2026-05-11 07:44:43 +08:00
mumu
629335852e docs: Clean root helper files (#1203)
* chore: clean root helper files

* fix: forward quick smoke args
2026-05-06 18:44:39 +08:00
mumu
0924dce274 fix: detect stale static bundles in build pipeline and at runtime (#1064) (#1121)
* fix: detect stale static bundles in build pipeline and at runtime (#1064)

Add a packaging-time sanity check and a backend startup self-check that
verifies index.html only references /assets/*.js and /assets/*.css files
that actually exist on disk. This is the most common root cause of the
'Preparing backend...' / blank-page bug seen on the Windows immutable
Release packages: vite emits a fresh index.html with new content hashes,
but the desktop packaging step picks up a stale static/ directory, so
the browser receives a 404 (returned as application/json) for the main
bundle and refuses to execute it.

- scripts/check_static_assets.py: cross-platform sanity script.
- scripts/build-backend{.ps1,-macos.sh}: run the script after npm build
  on the source static/, and again after PyInstaller on the packaged
  static directory; fail the build on mismatch.
- api/app.py: log an actionable ERROR when an inconsistency is detected
  at startup so the root cause appears in logs/desktop.log instead of
  surfacing as a silent blank page.
- api/app.py: replace the StaticFiles mount with an explicit /assets/*
  route so misses return a plain-text 404 with a JS/CSS Content-Type,
  not the default JSON error response that masked diagnosis in #1064.
- tests/test_static_assets_consistency.py: 7 deterministic tests for
  both code paths.

Refs #1064 #1065 #1050
2026-04-25 20:22:59 +08:00
mumu
e2bff55ce4 fix: restore pypi litellm install path (#858)
* fix: restore pypi litellm install path

* chore: relax litellm lower bound to historical minimum
2026-03-26 00:16:43 +08:00
zhulinsen
520c651e66 fix: restore windows desktop release build 2026-03-24 22:43:26 +08:00
mumu
c00dff17d3 fix: stabilize backend ci dependency install (#835)
* fix: stabilize backend ci dependency install

* fix: split backend gate workflow phases

* fix: retry backend ci dependency install

* fix: install litellm from github source
2026-03-24 21:42:39 +08:00
LouisHong
f7101b447d #730 [PR2] 股票输入框自动补全 - 拓展索引生成脚本,支持 A股/港股/美股三市场 (#798)
* feat(autocomplete): refactor index generator to support Tushare and multi-market

* docs: update changelog and README for multi-market autocomplete

- Add Unreleased entries for Tushare stock list fetcher, multi-market
  index generation scripts, and updated index data
- Update README to reflect A-share/HK/US coverage instead of
  A-share-only first phase
- Add examples for HK and US stock autocomplete (tencent, aapl)
- Reference TUSHARE_STOCK_LIST_GUIDE.md for index update workflow

* fix: deduplicate US autocomplete symbols
2026-03-22 20:34:34 +08:00
LouisHong
73d524a186 #730 [PR1] 首页股票分析输入框自动补全 AutoComplete (#775)
* feat(autocomplete): rebuild web autocomplete mvp

* feat(autocomplete): add error boundary and runtime fallback

Add error boundary and runtime error handling to improve autocomplete stability:

- Add StockAutocompleteBoundary class component to catch render errors
- Add FallbackInput component for graceful degradation
- Add runtimeFallback state and error handling in useAutocomplete hook
- Wrap search logic with try-catch to prevent crashes
- Add comprehensive tests for error scenarios

This ensures the autocomplete degrades to a plain input when:
- Index loading fails (existing behavior)
- Runtime search throws (new)
- Component tree throws during render (new)

* feat(autocomplete): add input validation and optimize name resolution

- Add early rejection for obviously invalid mixed alphanumeric input
- Skip expensive AkShare/fuzzy fallback for non-CJK free text
- Enhance frontend validation with isObviouslyInvalidStockQuery
- Increase minimum query length from 1 to 2 characters
- Add comprehensive test coverage for validation logic
- Update E2E test placeholder text to reflect new capabilities

These changes address code review feedback about:
- Preventing abuse from invalid input patterns
- Improving performance by avoiding unnecessary network calls
- Ensuring consistent validation between frontend and backend

* fix(autocomplete): harden input validation and runtime guards

* update doc

* style(autocomplete): adjust suggestion item hover effect

- Reduce hover background opacity from 35% to 25% for lighter visual effect
- Brighten hover color in dark theme from #257280 to #2dcae6

* fix(autocomplete): do not auto-highlight first suggestion to preserve raw input on Enter

* test(home): align report fixture with report language metadata

* fix: unify task queue stock dedupe key
2026-03-20 11:35:00 +08:00
mumu
b06c098a7c chore: harden ai governance assets (#738) 2026-03-17 23:23:31 +08:00
Frank
5c6cfe8238 fix(build): bundle tiktoken in PyInstaller builds (#554) Fixes #553 2026-03-09 21:19:26 +08:00
zhulinsen
bd0716aa91 fix: bundle litellm data files in PyInstaller build #patch
Add  to both Windows and macOS build scripts so
PyInstaller includes litellm's JSON data files (e.g.
model_prices_and_context_window_backup.json) in the packaged executable.

Without this, litellm raises FileNotFoundError at startup when it tries
to load the model cost map via pathlib.Path.read_text().

Affected files:
- scripts/build-backend.ps1
- scripts/build-backend-macos.sh
2026-03-02 21:43:50 +08:00
qlfabc
a67933e226 fix: 修复 ARCH_ARGS 空数组导致的 unbound variable 错误 (#458)
在 set -u 模式下,空数组 '${ARCH_ARGS[@]}' 会触发 unbound variable 错误。
添加数组长度检查,仅在 ARCH_ARGS 非空时传递参数。

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 16:41:26 +08:00
Krane
b2326e9439 Feature/Github Action自动打包发布到releases (#426)
* fix: 客户端打包脚本修复

* fix: Github Action package

* fix: Support Windows portable macOS x64

* fix: update macos version

* fix: exe use nsis

---------

Co-authored-by: mumu <42829555+ZhuLinsen@users.noreply.github.com>
2026-02-26 21:22:31 +08:00
Alfred
32162ff745 feat: Web 页面密码验证 (Issue #320, #349) (#351)
* feat(auth): Web 登录认证与 Settings 保护 (Issue #320, #349)

- 新增 ADMIN_AUTH_ENABLED 开关,启用后需登录才能访问 Web UI 和 API
- 首次访问时在网页设置初始密码,凭证存储于 data/.admin_password_hash
- Settings 页面及 /api/v1/* 在启用认证后需登录访问,保护 API 密钥等敏感配置
- 系统设置中可修改密码,密码输入框支持眼睛图标显示/隐藏
- CLI: python -m src.auth reset_password 可重置密码
- 错误提示统一为中文
- 更新 README、full-guide、CHANGELOG

* fix: 凭证文件权限 + ESLint 修复

- src/auth.py: .session_secret 创建后显式 chmod(0o600)
- Pagination.tsx: PageButton 移至组件外,避免 render 内创建组件
- useTaskStream.ts: connectRef 解决闭包引用;isConnected 改用 useState;disconnect setState 延后执行
- HomePage.tsx: 初始加载 useEffect 添加 exhaustive-deps 注释

* test(auth): add unit and integration tests for auth (Issue #320, #349)

- tests/test_auth.py: password validation, hash verification, session, rate limit, set/change/overwrite password
- tests/test_auth_api.py: login, logout, change-password, API protection (401 without session)
- scripts/ci_gate.sh: add src/auth.py to py_compile

* fix(test): disable auth in system_config_api tests to fix 401

* fix: remove duplicate PageButton declaration in Pagination.tsx

Fixes #320
Fixes #349
2026-02-20 21:47:19 +08:00
mumu
498770616f feat(ci): harden smoke gates and automated release pipeline #minor (#336)
- add scripts/ci_gate.sh as unified backend gate entry

- restructure CI into backend-gate/docker-build/web-gate with frontend path detection

- add network-smoke non-blocking workflow for scheduled/manual network checks

- harden docker-publish with tag/manual release_tag flow, semver + changelog validation, and pre-publish docker smoke

- expand PR review and AI review coverage to code/docs/config/workflow changes

- align PR template and contributor docs with AGENTS.md review requirements

- add pytest markers and python-multipart dependency; restore test setup in get_latest_data tests
2026-02-15 23:05:56 +08:00
Krane
64a263da85 Optimize/新增Mac平台打包脚本,优化桌面端启动速度 (#294)
* feat: mac 打包脚本

* fix: 启动速度优化

* fix: 启动速度优化
2026-02-10 22:58:45 +08:00
Krane
2ac96674fe feat: Support electron desktop mode 新增Electron Windows桌面端打包配置 (#264)
* feat: Support `electron` desktop mode

* fix: remove package-lock.json
2026-02-06 20:25:17 +08:00