@v587d/capital-generation 2.7.7 → 2.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/README.md +7 -5
  3. package/THIRD_PARTY_NOTICES.md +24 -3
  4. package/capital-config/client.js +4 -4
  5. package/capital-config/package.json +1 -1
  6. package/capital-watchlist/client.js +3 -3
  7. package/capital-watchlist/client.src.cjs +4 -4
  8. package/capital-watchlist/package.json +1 -1
  9. package/chart-ui/package.json +1 -1
  10. package/lib/agents/selected-skills-provider.js +41 -8
  11. package/lib/chart/source-token.js +18 -3
  12. package/lib/data-collector/dataset-tools.js +4 -2
  13. package/lib/data-collector/describe.d.ts +4 -0
  14. package/lib/data-collector/describe.js +11 -1
  15. package/lib/index.d.ts +17 -0
  16. package/lib/index.js +50 -18
  17. package/lib/web-retriever/local-fetch.d.ts +1 -1
  18. package/lib/web-retriever/local-fetch.js +1 -1
  19. package/lib/web-retriever/wind-client.d.ts +1 -1
  20. package/lib/web-retriever/wind-client.js +1 -1
  21. package/package.json +3 -1
  22. package/preset/capital-generation/agent.patch.yml +1 -0
  23. package/preset/capital-generation/skills/capital-data-protocol/SKILL.md +4 -0
  24. package/preset/capital-generation/skills/capital-equity-research/SKILL.md +1 -1
  25. package/preset/capital-generation/skills/capital-orchestration/SKILL.md +5 -0
  26. package/preset/capital-generation/skills/capital-visualization-protocol/SKILL.md +7 -7
  27. package/preset/capital-generation/skills/capital-web-protocol/SKILL.md +10 -3
  28. package/selected-skills/README.md +3 -1
  29. package/selected-skills/catalog.js +183 -0
  30. package/selected-skills/financeskills/LICENSE +21 -0
  31. package/selected-skills/financeskills/UPSTREAM.md +202 -0
  32. package/selected-skills/financeskills/skills/ai-anomaly-detection/EXAMPLE.md +21 -0
  33. package/selected-skills/financeskills/skills/ai-anomaly-detection/SKILL.md +84 -0
  34. package/selected-skills/financeskills/skills/ai-anomaly-detection/references/feature-engineering.md +20 -0
  35. package/selected-skills/financeskills/skills/ai-anomaly-detection/references/ml-algorithms.md +28 -0
  36. package/selected-skills/financeskills/skills/aro-computation/EXAMPLE.md +21 -0
  37. package/selected-skills/financeskills/skills/aro-computation/SKILL.md +82 -0
  38. package/selected-skills/financeskills/skills/aro-computation/references/aro-standards.md +22 -0
  39. package/selected-skills/financeskills/skills/aro-computation/references/pv-math.md +27 -0
  40. package/selected-skills/financeskills/skills/audit-checklist/EXAMPLE.md +17 -0
  41. package/selected-skills/financeskills/skills/audit-checklist/SKILL.md +77 -0
  42. package/selected-skills/financeskills/skills/audit-checklist/references/internal-controls.md +36 -0
  43. package/selected-skills/financeskills/skills/audit-checklist/references/isa-standards.md +26 -0
  44. package/selected-skills/financeskills/skills/automated-reconciliation/EXAMPLE.md +21 -0
  45. package/selected-skills/financeskills/skills/automated-reconciliation/SKILL.md +87 -0
  46. package/selected-skills/financeskills/skills/automated-reconciliation/assets/reconciliation-statement-template.md +31 -0
  47. package/selected-skills/financeskills/skills/automated-reconciliation/references/fuzzy-logic.md +27 -0
  48. package/selected-skills/financeskills/skills/automated-reconciliation/references/rec-controls.md +28 -0
  49. package/selected-skills/financeskills/skills/banking-compliance/EXAMPLE.md +21 -0
  50. package/selected-skills/financeskills/skills/banking-compliance/SKILL.md +82 -0
  51. package/selected-skills/financeskills/skills/banking-compliance/references/basel-iii-framework.md +26 -0
  52. package/selected-skills/financeskills/skills/banking-compliance/references/risk-weights.md +32 -0
  53. package/selected-skills/financeskills/skills/budget-forecast/EXAMPLE.md +21 -0
  54. package/selected-skills/financeskills/skills/budget-forecast/SKILL.md +87 -0
  55. package/selected-skills/financeskills/skills/budget-forecast/references/forecasting-best-practices.md +26 -0
  56. package/selected-skills/financeskills/skills/budget-forecast/references/scenario-analysis.md +25 -0
  57. package/selected-skills/financeskills/skills/close-management/EXAMPLE.md +17 -0
  58. package/selected-skills/financeskills/skills/close-management/SKILL.md +85 -0
  59. package/selected-skills/financeskills/skills/close-management/references/close-task-library.md +32 -0
  60. package/selected-skills/financeskills/skills/company-valuation/EXAMPLE.md +21 -0
  61. package/selected-skills/financeskills/skills/company-valuation/SKILL.md +80 -0
  62. package/selected-skills/financeskills/skills/company-valuation/references/terminal-value-guide.md +33 -0
  63. package/selected-skills/financeskills/skills/corporate-consolidation/EXAMPLE.md +21 -0
  64. package/selected-skills/financeskills/skills/corporate-consolidation/SKILL.md +84 -0
  65. package/selected-skills/financeskills/skills/corporate-consolidation/references/consolidation-standard.md +28 -0
  66. package/selected-skills/financeskills/skills/corporate-consolidation/references/minority-interest.md +25 -0
  67. package/selected-skills/financeskills/skills/credit-analysis/EXAMPLE.md +21 -0
  68. package/selected-skills/financeskills/skills/credit-analysis/SKILL.md +84 -0
  69. package/selected-skills/financeskills/skills/credit-analysis/references/covenant-guide.md +26 -0
  70. package/selected-skills/financeskills/skills/crypto-accounting/EXAMPLE.md +21 -0
  71. package/selected-skills/financeskills/skills/crypto-accounting/SKILL.md +81 -0
  72. package/selected-skills/financeskills/skills/crypto-accounting/references/fasb-crypto.md +26 -0
  73. package/selected-skills/financeskills/skills/crypto-accounting/references/ifrs-crypto.md +25 -0
  74. package/selected-skills/financeskills/skills/cvp-breakeven/EXAMPLE.md +21 -0
  75. package/selected-skills/financeskills/skills/cvp-breakeven/SKILL.md +78 -0
  76. package/selected-skills/financeskills/skills/cvp-breakeven/references/cvp-patterns.md +28 -0
  77. package/selected-skills/financeskills/skills/debt-payoff/EXAMPLE.md +21 -0
  78. package/selected-skills/financeskills/skills/debt-payoff/SKILL.md +94 -0
  79. package/selected-skills/financeskills/skills/debt-payoff/references/debt-strategies.md +32 -0
  80. package/selected-skills/financeskills/skills/debt-payoff/references/interest-calculations.md +27 -0
  81. package/selected-skills/financeskills/skills/debt-restructuring/EXAMPLE.md +21 -0
  82. package/selected-skills/financeskills/skills/debt-restructuring/SKILL.md +79 -0
  83. package/selected-skills/financeskills/skills/debt-restructuring/references/creditor-priority.md +26 -0
  84. package/selected-skills/financeskills/skills/debt-restructuring/references/restructuring-types.md +24 -0
  85. package/selected-skills/financeskills/skills/deferred-tax/EXAMPLE.md +21 -0
  86. package/selected-skills/financeskills/skills/deferred-tax/SKILL.md +86 -0
  87. package/selected-skills/financeskills/skills/deferred-tax/references/td-catalogue.md +39 -0
  88. package/selected-skills/financeskills/skills/earned-value-mgmt/EXAMPLE.md +21 -0
  89. package/selected-skills/financeskills/skills/earned-value-mgmt/SKILL.md +79 -0
  90. package/selected-skills/financeskills/skills/earned-value-mgmt/references/forecasting-eac.md +27 -0
  91. package/selected-skills/financeskills/skills/earned-value-mgmt/references/pmi-evm.md +29 -0
  92. package/selected-skills/financeskills/skills/ecl-computation/EXAMPLE.md +21 -0
  93. package/selected-skills/financeskills/skills/ecl-computation/SKILL.md +85 -0
  94. package/selected-skills/financeskills/skills/ecl-computation/references/ifrs9-standard.md +27 -0
  95. package/selected-skills/financeskills/skills/ecl-computation/references/risk-modeling.md +26 -0
  96. package/selected-skills/financeskills/skills/esg-reporting/EXAMPLE.md +17 -0
  97. package/selected-skills/financeskills/skills/esg-reporting/SKILL.md +79 -0
  98. package/selected-skills/financeskills/skills/esg-reporting/references/ghg-protocol.md +22 -0
  99. package/selected-skills/financeskills/skills/esg-reporting/references/sasb-map.md +25 -0
  100. package/selected-skills/financeskills/skills/financial-analysis/EXAMPLE.md +21 -0
  101. package/selected-skills/financeskills/skills/financial-analysis/SKILL.md +108 -0
  102. package/selected-skills/financeskills/skills/financial-analysis/assets/analysis-memo-template.md +31 -0
  103. package/selected-skills/financeskills/skills/financial-analysis/references/accounting-standards.md +45 -0
  104. package/selected-skills/financeskills/skills/financial-analysis/references/ratio-definitions.md +14 -0
  105. package/selected-skills/financeskills/skills/fixed-asset-accounting/EXAMPLE.md +21 -0
  106. package/selected-skills/financeskills/skills/fixed-asset-accounting/SKILL.md +78 -0
  107. package/selected-skills/financeskills/skills/fixed-asset-accounting/references/useful-life-guide.md +30 -0
  108. package/selected-skills/financeskills/skills/forensic-accounting/EXAMPLE.md +21 -0
  109. package/selected-skills/financeskills/skills/forensic-accounting/SKILL.md +91 -0
  110. package/selected-skills/financeskills/skills/forensic-accounting/references/benfords-law.md +24 -0
  111. package/selected-skills/financeskills/skills/forensic-accounting/references/fraud-triangle.md +26 -0
  112. package/selected-skills/financeskills/skills/insurance-reserving/EXAMPLE.md +21 -0
  113. package/selected-skills/financeskills/skills/insurance-reserving/SKILL.md +82 -0
  114. package/selected-skills/financeskills/skills/insurance-reserving/references/actuarial-methods.md +33 -0
  115. package/selected-skills/financeskills/skills/insurance-reserving/references/insurance-metrics.md +26 -0
  116. package/selected-skills/financeskills/skills/intercompany-accounting/EXAMPLE.md +21 -0
  117. package/selected-skills/financeskills/skills/intercompany-accounting/SKILL.md +79 -0
  118. package/selected-skills/financeskills/skills/intercompany-accounting/references/elimination-entries.md +35 -0
  119. package/selected-skills/financeskills/skills/inventory-costing/EXAMPLE.md +21 -0
  120. package/selected-skills/financeskills/skills/inventory-costing/SKILL.md +80 -0
  121. package/selected-skills/financeskills/skills/inventory-costing/references/costing-examples.md +31 -0
  122. package/selected-skills/financeskills/skills/investment-analysis/EXAMPLE.md +21 -0
  123. package/selected-skills/financeskills/skills/investment-analysis/SKILL.md +82 -0
  124. package/selected-skills/financeskills/skills/investment-analysis/references/competitive-advantage.md +31 -0
  125. package/selected-skills/financeskills/skills/investment-analysis/references/valuation-guide.md +29 -0
  126. package/selected-skills/financeskills/skills/journal-entry/EXAMPLE.md +21 -0
  127. package/selected-skills/financeskills/skills/journal-entry/SKILL.md +94 -0
  128. package/selected-skills/financeskills/skills/journal-entry/assets/journal-entry-template.md +21 -0
  129. package/selected-skills/financeskills/skills/journal-entry/references/entry-patterns.md +51 -0
  130. package/selected-skills/financeskills/skills/lbo-modeling/EXAMPLE.md +21 -0
  131. package/selected-skills/financeskills/skills/lbo-modeling/SKILL.md +88 -0
  132. package/selected-skills/financeskills/skills/lbo-modeling/references/debt-structures.md +22 -0
  133. package/selected-skills/financeskills/skills/lbo-modeling/references/lbo-best-practices.md +27 -0
  134. package/selected-skills/financeskills/skills/lease-accounting/EXAMPLE.md +21 -0
  135. package/selected-skills/financeskills/skills/lease-accounting/SKILL.md +88 -0
  136. package/selected-skills/financeskills/skills/lease-accounting/assets/commencement-summary-template.md +28 -0
  137. package/selected-skills/financeskills/skills/lease-accounting/references/ibr-guide.md +26 -0
  138. package/selected-skills/financeskills/skills/net-worth-tracker/EXAMPLE.md +21 -0
  139. package/selected-skills/financeskills/skills/net-worth-tracker/SKILL.md +98 -0
  140. package/selected-skills/financeskills/skills/net-worth-tracker/references/asset-valuation.md +40 -0
  141. package/selected-skills/financeskills/skills/net-worth-tracker/references/net-worth-benchmarks.md +33 -0
  142. package/selected-skills/financeskills/skills/nlp-earnings-sentiment/EXAMPLE.md +17 -0
  143. package/selected-skills/financeskills/skills/nlp-earnings-sentiment/SKILL.md +77 -0
  144. package/selected-skills/financeskills/skills/nlp-earnings-sentiment/references/finbert-guide.md +26 -0
  145. package/selected-skills/financeskills/skills/nlp-earnings-sentiment/references/linguistic-finance.md +23 -0
  146. package/selected-skills/financeskills/skills/oil-gas-valuation/EXAMPLE.md +21 -0
  147. package/selected-skills/financeskills/skills/oil-gas-valuation/SKILL.md +86 -0
  148. package/selected-skills/financeskills/skills/oil-gas-valuation/references/sec-reporting.md +22 -0
  149. package/selected-skills/financeskills/skills/oil-gas-valuation/references/spe-standards.md +25 -0
  150. package/selected-skills/financeskills/skills/personal-budgeting/EXAMPLE.md +21 -0
  151. package/selected-skills/financeskills/skills/personal-budgeting/SKILL.md +100 -0
  152. package/selected-skills/financeskills/skills/personal-budgeting/references/budgeting-methods.md +40 -0
  153. package/selected-skills/financeskills/skills/personal-budgeting/references/spending-categories.md +40 -0
  154. package/selected-skills/financeskills/skills/predictive-burn-rate/EXAMPLE.md +21 -0
  155. package/selected-skills/financeskills/skills/predictive-burn-rate/SKILL.md +82 -0
  156. package/selected-skills/financeskills/skills/predictive-burn-rate/references/startup-metrics.md +27 -0
  157. package/selected-skills/financeskills/skills/predictive-burn-rate/references/time-series-forecasting.md +22 -0
  158. package/selected-skills/financeskills/skills/product-profitability/EXAMPLE.md +21 -0
  159. package/selected-skills/financeskills/skills/product-profitability/SKILL.md +83 -0
  160. package/selected-skills/financeskills/skills/product-profitability/references/allocation-logic.md +28 -0
  161. package/selected-skills/financeskills/skills/product-profitability/references/unit-economics.md +30 -0
  162. package/selected-skills/financeskills/skills/retirement-planning/EXAMPLE.md +21 -0
  163. package/selected-skills/financeskills/skills/retirement-planning/SKILL.md +98 -0
  164. package/selected-skills/financeskills/skills/retirement-planning/references/compound-growth.md +38 -0
  165. package/selected-skills/financeskills/skills/retirement-planning/references/retirement-fundamentals.md +29 -0
  166. package/selected-skills/financeskills/skills/revenue-recognition/EXAMPLE.md +21 -0
  167. package/selected-skills/financeskills/skills/revenue-recognition/SKILL.md +86 -0
  168. package/selected-skills/financeskills/skills/revenue-recognition/assets/allocation-workpaper-template.md +30 -0
  169. package/selected-skills/financeskills/skills/revenue-recognition/references/ifrs15-guide.md +28 -0
  170. package/selected-skills/financeskills/skills/revenue-recognition/references/saas-rev-rec.md +26 -0
  171. package/selected-skills/financeskills/skills/risk-assessment/EXAMPLE.md +21 -0
  172. package/selected-skills/financeskills/skills/risk-assessment/SKILL.md +83 -0
  173. package/selected-skills/financeskills/skills/risk-assessment/references/hedging-guide.md +24 -0
  174. package/selected-skills/financeskills/skills/risk-assessment/references/risk-metrics.md +24 -0
  175. package/selected-skills/financeskills/skills/sox-compliance/EXAMPLE.md +17 -0
  176. package/selected-skills/financeskills/skills/sox-compliance/SKILL.md +88 -0
  177. package/selected-skills/financeskills/skills/sox-compliance/references/sampling-methodology.md +27 -0
  178. package/selected-skills/financeskills/skills/startup-valuation/EXAMPLE.md +21 -0
  179. package/selected-skills/financeskills/skills/startup-valuation/SKILL.md +88 -0
  180. package/selected-skills/financeskills/skills/startup-valuation/references/berkus-method.md +25 -0
  181. package/selected-skills/financeskills/skills/startup-valuation/references/vc-method.md +23 -0
  182. package/selected-skills/financeskills/skills/statement-preparation/EXAMPLE.md +21 -0
  183. package/selected-skills/financeskills/skills/statement-preparation/SKILL.md +86 -0
  184. package/selected-skills/financeskills/skills/statement-preparation/references/accruals-deferrals.md +24 -0
  185. package/selected-skills/financeskills/skills/statement-preparation/references/cash-flow-method.md +32 -0
  186. package/selected-skills/financeskills/skills/tax-efficient-investing/EXAMPLE.md +21 -0
  187. package/selected-skills/financeskills/skills/tax-efficient-investing/SKILL.md +97 -0
  188. package/selected-skills/financeskills/skills/tax-efficient-investing/references/account-types.md +33 -0
  189. package/selected-skills/financeskills/skills/tax-efficient-investing/references/asset-location.md +36 -0
  190. package/selected-skills/financeskills/skills/tax-planning/EXAMPLE.md +21 -0
  191. package/selected-skills/financeskills/skills/tax-planning/SKILL.md +93 -0
  192. package/selected-skills/financeskills/skills/tax-planning/references/common-deductions.md +28 -0
  193. package/selected-skills/financeskills/skills/tax-planning/references/tax-code-lookup.md +25 -0
  194. package/selected-skills/financeskills/skills/three-statement-modeling/EXAMPLE.md +21 -0
  195. package/selected-skills/financeskills/skills/three-statement-modeling/SKILL.md +84 -0
  196. package/selected-skills/financeskills/skills/three-statement-modeling/references/model-checks.md +32 -0
  197. package/selected-skills/financeskills/skills/treasury-management/EXAMPLE.md +21 -0
  198. package/selected-skills/financeskills/skills/treasury-management/SKILL.md +83 -0
  199. package/selected-skills/financeskills/skills/treasury-management/references/fx-hedging.md +27 -0
  200. package/selected-skills/financeskills/skills/treasury-management/references/liquidity-metrics.md +24 -0
  201. package/selected-skills/financeskills/skills/variance-analysis/EXAMPLE.md +21 -0
  202. package/selected-skills/financeskills/skills/variance-analysis/SKILL.md +78 -0
  203. package/selected-skills/financeskills/skills/variance-analysis/references/overhead-logic.md +24 -0
  204. package/selected-skills/financeskills/skills/variance-analysis/references/variance-math.md +35 -0
  205. package/selected-skills/financeskills/skills/venture-debt/EXAMPLE.md +21 -0
  206. package/selected-skills/financeskills/skills/venture-debt/SKILL.md +84 -0
  207. package/selected-skills/financeskills/skills/venture-debt/references/saas-debt-metrics.md +26 -0
  208. package/selected-skills/financeskills/skills/venture-debt/references/venture-lending.md +23 -0
  209. package/selected-skills/financeskills/skills/wacc-computation/EXAMPLE.md +21 -0
  210. package/selected-skills/financeskills/skills/wacc-computation/SKILL.md +98 -0
  211. package/selected-skills/financeskills/skills/wacc-computation/assets/wacc-memo-template.md +40 -0
  212. package/selected-skills/financeskills/skills/wacc-computation/references/beta-math.md +24 -0
  213. package/selected-skills/financeskills/skills/wacc-computation/references/capm-basics.md +24 -0
  214. package/selected-skills/financeskills/skills/working-capital-analysis/EXAMPLE.md +21 -0
  215. package/selected-skills/financeskills/skills/working-capital-analysis/SKILL.md +83 -0
  216. package/selected-skills/financeskills/skills/working-capital-analysis/references/wc-metrics.md +30 -0
  217. package/selected-skills/quant-agent-skills/LICENSE +21 -0
  218. package/selected-skills/quant-agent-skills/UPSTREAM.md +111 -0
  219. package/selected-skills/quant-agent-skills/skills/cross-market-listing-choice/SKILL.md +105 -0
  220. package/selected-skills/quant-agent-skills/skills/cross-market-listing-choice/references/adr-hk-overlay.md +45 -0
  221. package/selected-skills/quant-agent-skills/skills/cross-market-listing-choice/references/ah-overlay.md +44 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v587d/capital-config",
3
- "version": "2.7.7",
3
+ "version": "2.7.9",
4
4
  "description": "Capital 模式的取数凭据与偏好配置行:卡片坐在 @v587d/capital-generation 插件主页的「配置」段,点这一行本身没有表单。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -5,7 +5,7 @@ window.__ModuleLoader__.load({
5
5
  var module = { exports: {} }
6
6
  var exports = module.exports
7
7
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' })
8
- "use strict";var S=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var nt=Object.getOwnPropertyNames;var ot=Object.prototype.hasOwnProperty;var ct=(e,a,t)=>()=>{if(t)throw t[0];try{return e&&(a=e(e=0)),a}catch(s){throw t=[s],s}};var dt=(e,a)=>{for(var t in a)S(e,t,{get:a[t],enumerable:!0})},pt=(e,a,t,s)=>{if(a&&typeof a=="object"||typeof a=="function")for(let i of nt(a))!ot.call(e,i)&&i!==t&&S(e,i,{get:()=>a[i],enumerable:!(s=st(a,i))||s.enumerable});return e};var ht=e=>pt(S({},"__esModule",{value:!0}),e);var H={};dt(H,{ASSET_TYPES:()=>ut,HOLDABLE_ASSET_TYPES:()=>P,MAX_ROW_WEIGHT_PCT:()=>wt,MAX_TOTAL_WEIGHT_PCT:()=>ft,holdingWeight:()=>I,isHoldable:()=>mt,otherHeldWeightPct:()=>R,weightCeiling:()=>gt});var ut,P,mt,wt,ft,I,R,gt,z=ct(()=>{"use strict";ut=["a-share","a-share-index","fund-etf","hk-stock","hk-index","us-stock","us-index"],P=["a-share","fund-etf","hk-stock","us-stock"],mt=e=>P.includes(e?.asset_type),wt=100,ft=120,I=e=>e?.holding===null||e?.holding===void 0?0:e?.holding?.weight_pct??0,R=(e,a)=>e.reduce((t,s)=>s?.thscode===a?t:t+I(s),0),gt=(e,a)=>Math.max(0,Math.min(100,120-R(e,a)))});var{createElement:l,useEffect:bt,useState:M}=require("react"),{createSnapshotStore:xt}=require("@deepseek-ai/dsh-client-store"),{IconChecklistOutlineRegular:yt,IconCloseOutlineRegular:O,IconDatabaseOutlineRegular:vt,IconEllipsisOutlineRegular:kt,IconGoalOutlineRegular:Nt,IconListPenOutlineRegular:St,IconPinOutlineRegular:_t,IconRefreshOutlineRegular:Ct,IconSearchOutlineRegular:Et,IconTrashOutlineRegular:Tt,Menu:At,MenuItemButton:$t,Modal:Pt,Switch:It}=require("@deepseek-ai/dsh-client-ui-primitives"),{isHoldable:F,weightCeiling:W}=(z(),ht(H)),f="capital-watchlist",_="capital.watchlist",L="conversation.input.overlay",j="/capital-watchlist",Rt="capital-generation",Ht=300,C=10,D="capital-watchlist-css",zt={"command.label":"\u81EA\u9009\u80A1","command.description":"\u6DFB\u52A0 / \u67E5\u770B / \u5220\u9664\u81EA\u9009\u80A1",title:"\u81EA\u9009\u80A1",close:"\u5173\u95ED",searchPlaceholder:"\u8F93\u5165\u8BC1\u5238\u4EE3\u7801\u6216\u540D\u79F0\uFF0C\u652F\u6301A\u80A1/\u6E2F\u80A1/\u7F8E\u80A1",add:"\u6DFB\u52A0",added:"\u5DF2\u6DFB\u52A0",refreshing:"\u5237\u65B0\u4E2D\u2026",refresh:"\u5237\u65B0\u62A5\u4EF7",loading:"\u6B63\u5728\u8BFB\u53D6\u6E05\u5355\u2026",empty:"\u8FD8\u6CA1\u6709\u81EA\u9009\u80A1\uFF0C\u7528\u4E0A\u9762\u7684\u8F93\u5165\u6846\u6DFB\u52A0\u3002",colName:"\u540D\u79F0",colQuote:"\u6700\u65B0\u4EF7 / \u6DA8\u8DCC\u5E45",colAction:"\u64CD\u4F5C",updated:"\u66F4\u65B0\u65F6\u95F4",notRefreshed:"\u672A\u5237\u65B0",stale:"\u4E0A\u4E00\u6B21\u5FEB\u7167",exchangeTime:"\u4EA4\u6613\u6240\u65F6\u95F4",noChangePct:"\u6682\u65E0\u6DA8\u8DCC\u6570\u636E",typeAShare:"A\u80A1",typeHkStock:"\u6E2F\u80A1",typeUsStock:"\u7F8E\u80A1",typeAIndex:"A\u6307",typeHkIndex:"\u6E2F\u6307",typeUsIndex:"\u7F8E\u6307",kindStock:"\u80A1\u7968",kindIndex:"\u6307\u6570",kindEtf:"ETF",remove:"\u79FB\u9664",more:"\u66F4\u591A",pin:"\u7F6E\u9876",holdingWeightLabel:"\u6301\u4ED3\u6BD4\u4F8B",holdingStepper:"\u6301\u4ED3\u6BD4\u4F8B\uFF08\u6BCF\u6863 10 \u4E2A\u767E\u5206\u70B9\uFF09",holdingStepUp:"\u589E\u52A0\u6301\u4ED3\u6BD4\u4F8B",holdingStepDown:"\u51CF\u5C11\u6301\u4ED3\u6BD4\u4F8B",holdingName:"\u6301\u4ED3",predict:"\u9884\u6D4B",predictTip:"AI\u9884\u6D4B\u8BE5\u8BC1\u5238\u6807\u7684",review:"\u590D\u76D8",reviewTip:"AI\u590D\u76D8\u8BE5\u8BC1\u5238\u6807\u7684",predictPromptPrefix:"\u8BF7\u9884\u6D4B ",predictPromptSuffix:"\uFF1A\u672A\u6765 5 \u4E2A\u4EA4\u6613\u65E5\u7684\u8D70\u52BF\u4E0E\u5173\u952E\u70B9\u4F4D\uFF0C\u8BF4\u660E\u4F9D\u636E\uFF0C\u5E76\u7ED9\u51FA\u5224\u65AD\u7684\u4E0D\u786E\u5B9A\u6027\u3002",reviewPromptPrefix:"\u8BF7\u590D\u76D8 ",reviewPromptSuffix:"\uFF1A\u4ECA\u65E5\u8D70\u52BF\u4E0E\u91CF\u4EF7\u3001\u8FD1 20 \u65E5\u8D8B\u52BF\u3001\u57FA\u7840\u9762\u3001\u6D88\u606F\u9762\uFF0C\u7ED9\u51FA\u7ED3\u8BBA\u548C\u5FC5\u8981\u98CE\u9669\u8BC4\u4F30\u3002",searching:"\u641C\u7D22\u4E2D\u2026",composingHint:"\u8F93\u5165\u5B8C\u6210\u540E\u81EA\u52A8\u641C\u7D22",clearInput:"\u6E05\u7A7A\u8F93\u5165",confirmTitle:"\u786E\u8BA4\u79FB\u9664\uFF1F",confirmDescPrefix:"\u786E\u5B9A\u5C06 ",confirmDescSuffix:" \u4ECE\u81EA\u9009\u4E2D\u79FB\u9664\u5417\uFF1F",confirmCancel:"\u53D6\u6D88",confirmOk:"\u786E\u8BA4\u79FB\u9664",truncated:"\u6CA1\u6709\u66F4\u591A\uFF0C\u8BF7\u8F93\u5165\u51C6\u786E\u7684\u8BC1\u5238\u4EE3\u7801\u6216\u540D\u79F0\u3002",filterAll:"\u5168\u90E8",filterLabel:"\u6309\u5E02\u573A\u7B5B\u9009\u5019\u9009",filterNoHit:"\u8FD9\u4E2A\u5E02\u573A\u4E0B\u6CA1\u6709\u5339\u914D\u7684\u6807\u7684\u3002",noHit:"\u6CA1\u6709\u5339\u914D\u7684\u6807\u7684\uFF08A\u80A1 / \u6E2F\u80A1 / \u7F8E\u80A1\uFF0C\u542B\u6307\u6570\u4E0E\u573A\u5185\u57FA\u91D1\uFF09\u3002","error.invalid_query":"\u8F93\u5165\u4E0D\u88AB\u63A5\u53D7","error.not_found":"\u6CA1\u6709\u627E\u5230\u8BE5\u6807\u7684","error.ambiguous":"\u547D\u4E2D\u591A\u6761\uFF0C\u8BF7\u4ECE\u5019\u9009\u91CC\u9009\u4E00\u6761","error.list_full":"\u81EA\u9009\u80A1\u6700\u591A {max} \u6761\uFF0C\u5148\u5220\u4E00\u6761\u518D\u52A0","error.list_full_noMax":"\u81EA\u9009\u80A1\u5DF2\u8FBE\u4E0A\u9650\uFF0C\u5148\u5220\u4E00\u6761\u518D\u52A0","error.credential_missing":"\u672A\u914D\u7F6E Fuyao \u5BC6\u94A5\uFF1A\u5728\u300C\u63D2\u4EF6\u300D\u9875\u7684 Capital \u6A21\u5F0F\u5361\u7247\u91CC\u586B API Key\uFF08\u53EA\u5F71\u54CD A \u80A1\u90A3\u4E00\u8DEF\uFF0C\u6E2F\u7F8E\u80A1\u7167\u5E38\u7528\uFF09","error.rate_limited":"\u884C\u60C5\u670D\u52A1\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5","error.fuyao_unavailable":"A \u80A1\u884C\u60C5\u6682\u65F6\u53D6\u4E0D\u5230\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5","error.tencent_unavailable":"\u6E2F\u7F8E\u80A1\u884C\u60C5\u6682\u65F6\u53D6\u4E0D\u5230\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5","error.quote_unavailable":"\u8BE5\u6807\u7684\u6CA1\u6709\u53EF\u7528\u62A5\u4EF7","error.refresh_timeout":"\u5237\u65B0\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5","error.store_unavailable":"\u81EA\u9009\u80A1\u5B58\u50A8\u4E0D\u53EF\u7528","error.unauthorized":"\u767B\u5F55\u72B6\u6001\u5DF2\u5931\u6548\uFF1A\u8BF7\u5148\u56DE\u5230\u5BBF\u4E3B\u7A97\u53E3\u91CD\u65B0\u767B\u5F55",errorSuffix:"\uFF08\u5176\u4ED6\u6807\u7684\u4ECD\u662F\u4E0A\u4E00\u6B21\u6210\u529F\u5FEB\u7167\uFF09","partial.a-share":"A \u80A1\u68C0\u7D22\u4E0D\u53EF\u7528\uFF1A","partial.hk":"\u6E2F\u80A1\u68C0\u7D22\u4E0D\u53EF\u7528\uFF1A","partial.us":"\u7F8E\u80A1\u68C0\u7D22\u4E0D\u53EF\u7528\uFF1A"},Mt={"command.label":"Watchlist","command.description":"Add / view / remove watched symbols",title:"Watchlist",close:"Close",searchPlaceholder:"Symbol code or name \u2014 A-share / HK / US",add:"Add",added:"Added",refreshing:"Refreshing\u2026",refresh:"Refresh quotes",loading:"Loading list\u2026",empty:"No symbols yet \u2014 use the input above to add one.",colName:"Symbol",colQuote:"Last / change",colAction:"Actions",updated:"Updated",notRefreshed:"Not refreshed",stale:"last snapshot",exchangeTime:"exchange time",noChangePct:"No change data yet",typeAShare:"A-Share",typeHkStock:"HK",typeUsStock:"US",typeAIndex:"A-Index",typeHkIndex:"HK-Index",typeUsIndex:"US-Index",kindStock:"stock",kindIndex:"index",kindEtf:"ETF",remove:"Remove",more:"More",pin:"Pin to top",holdingWeightLabel:"Holding weight",holdingStepper:"Holding weight, in steps of 10 percentage points",holdingStepUp:"Increase holding weight",holdingStepDown:"Decrease holding weight",holdingName:"Holding",predict:"Predict",predictTip:"AI prediction for this symbol",review:"Review",reviewTip:"AI review of this symbol",predictPromptPrefix:"Predict ",predictPromptSuffix:" over the next 5 sessions: the likely path and key levels, the evidence behind the call, and how uncertain it is.",reviewPromptPrefix:"Review ",reviewPromptSuffix:" with today's trend and volume, the last 20 sessions, fundamental, news, then a conclusion and the necessary risks analysis.",searching:"Searching\u2026",composingHint:"Search runs when you finish typing",clearInput:"Clear input",confirmTitle:"Remove this symbol?",confirmDescPrefix:"Remove ",confirmDescSuffix:" from your watchlist?",confirmCancel:"Cancel",confirmOk:"Remove",truncated:"No more candidates \u2014 enter an accurate code or name.",filterAll:"All",filterLabel:"Filter candidates by market",filterNoHit:"No matching symbol in this market.",noHit:"No matching symbol (A-share / HK / US, including indices and listed funds).","error.invalid_query":"Input not accepted","error.not_found":"Symbol not found","error.ambiguous":"Multiple hits \u2014 pick one candidate","error.list_full":"Watchlist holds at most {max} symbols \u2014 remove one first","error.list_full_noMax":"Watchlist is full \u2014 remove one first","error.credential_missing":"No Fuyao API key: set it on the Capital card in the Plugins page (A-share quotes only \u2014 HK and US keep working)","error.rate_limited":"Quote service is rate limited \u2014 try again later","error.fuyao_unavailable":"A-share quotes unavailable \u2014 try again later","error.tencent_unavailable":"HK / US quotes unavailable \u2014 try again later","error.quote_unavailable":"No quote for this symbol","error.refresh_timeout":"Refresh timed out \u2014 try again later","error.store_unavailable":"Watchlist storage unavailable","error.unauthorized":"Session expired \u2014 sign back in to the host first",errorSuffix:" (other symbols still show their last good snapshot)","partial.a-share":"A-share search unavailable: ","partial.hk":"HK search unavailable: ","partial.us":"US search unavailable: "},Ot={"a-share":"typeAShare","hk-stock":"typeHkStock","us-stock":"typeUsStock","a-share-index":"typeAIndex","hk-index":"typeHkIndex","us-index":"typeUsIndex","fund-etf":"typeAShare"},Ft={"a-share":"kindStock","hk-stock":"kindStock","us-stock":"kindStock","a-share-index":"kindIndex","hk-index":"kindIndex","us-index":"kindIndex","fund-etf":"kindEtf"};function Lt(e,a){let t=Ot[e];return t===void 0?String(e??""):a(t)}function jt(e,a){let t=Ft[e];return t===void 0?String(e??""):a(t)}var Dt=/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F\u00AD\u200B-\u200F\u2028\u2029\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/gu;function T(e){return String(e??"").replace(Dt,"")}function y(e){return Array.isArray(e)?e.map(a=>a===null||typeof a!="object"?a:{...a,name:T(a.name)}):e}var Ut={"a-share":"capital-watchlist-tag-cn","a-share-index":"capital-watchlist-tag-cn","fund-etf":"capital-watchlist-tag-cn","hk-stock":"capital-watchlist-tag-hk","hk-index":"capital-watchlist-tag-hk","us-stock":"capital-watchlist-tag-us","us-index":"capital-watchlist-tag-us"},B=[{id:"all"},{id:"cn",label:"CN"},{id:"hk",label:"HK"},{id:"us",label:"US"}],U=e=>e.exchange==="HK"?"hk":e.exchange==="US"?"us":"cn",qt=`
8
+ "use strict";var S=Object.defineProperty;var st=Object.getOwnPropertyDescriptor;var nt=Object.getOwnPropertyNames;var ot=Object.prototype.hasOwnProperty;var ct=(e,a,t)=>()=>{if(t)throw t[0];try{return e&&(a=e(e=0)),a}catch(s){throw t=[s],s}};var dt=(e,a)=>{for(var t in a)S(e,t,{get:a[t],enumerable:!0})},pt=(e,a,t,s)=>{if(a&&typeof a=="object"||typeof a=="function")for(let i of nt(a))!ot.call(e,i)&&i!==t&&S(e,i,{get:()=>a[i],enumerable:!(s=st(a,i))||s.enumerable});return e};var ht=e=>pt(S({},"__esModule",{value:!0}),e);var H={};dt(H,{ASSET_TYPES:()=>ut,HOLDABLE_ASSET_TYPES:()=>P,MAX_ROW_WEIGHT_PCT:()=>wt,MAX_TOTAL_WEIGHT_PCT:()=>ft,holdingWeight:()=>I,isHoldable:()=>mt,otherHeldWeightPct:()=>R,weightCeiling:()=>gt});var ut,P,mt,wt,ft,I,R,gt,z=ct(()=>{"use strict";ut=["a-share","a-share-index","fund-etf","hk-stock","hk-index","us-stock","us-index"],P=["a-share","fund-etf","hk-stock","us-stock"],mt=e=>P.includes(e?.asset_type),wt=100,ft=120,I=e=>e?.holding===null||e?.holding===void 0?0:e?.holding?.weight_pct??0,R=(e,a)=>e.reduce((t,s)=>s?.thscode===a?t:t+I(s),0),gt=(e,a)=>Math.max(0,Math.min(100,120-R(e,a)))});var{createElement:l,useEffect:bt,useState:M}=require("react"),{createSnapshotStore:xt}=require("@deepseek-ai/dsh-client-store"),{IconChecklistOutlineRegular:vt,IconCloseOutlineRegular:O,IconDatabaseOutlineRegular:yt,IconEllipsisOutlineRegular:kt,IconGoalOutlineRegular:Nt,IconListPenOutlineRegular:St,IconPinOutlineRegular:_t,IconRefreshOutlineRegular:Ct,IconSearchOutlineRegular:Et,IconTrashOutlineRegular:Tt,Menu:At,MenuItemButton:$t,Modal:Pt,Switch:It}=require("@deepseek-ai/dsh-client-ui-primitives"),{isHoldable:F,weightCeiling:W}=(z(),ht(H)),f="capital-watchlist",_="capital.watchlist",L="conversation.input.overlay",j="/capital-watchlist",Rt="capital-generation",Ht=300,C=10,D="capital-watchlist-css",zt={"command.label":"\u81EA\u9009\u80A1","command.description":"\u6DFB\u52A0 / \u67E5\u770B / \u5220\u9664\u81EA\u9009\u80A1",title:"\u81EA\u9009\u80A1",close:"\u5173\u95ED",searchPlaceholder:"\u8F93\u5165\u8BC1\u5238\u4EE3\u7801\u6216\u540D\u79F0\uFF0C\u652F\u6301A\u80A1/\u6E2F\u80A1/\u7F8E\u80A1",add:"\u6DFB\u52A0",added:"\u5DF2\u6DFB\u52A0",refreshing:"\u5237\u65B0\u4E2D\u2026",refresh:"\u5237\u65B0\u62A5\u4EF7",loading:"\u6B63\u5728\u8BFB\u53D6\u6E05\u5355\u2026",empty:"\u8FD8\u6CA1\u6709\u81EA\u9009\u80A1\uFF0C\u7528\u4E0A\u9762\u7684\u8F93\u5165\u6846\u6DFB\u52A0\u3002",colName:"\u540D\u79F0",colQuote:"\u6700\u65B0\u4EF7 / \u6DA8\u8DCC\u5E45",colAction:"\u64CD\u4F5C",updated:"\u66F4\u65B0\u65F6\u95F4",notRefreshed:"\u672A\u5237\u65B0",stale:"\u4E0A\u4E00\u6B21\u5FEB\u7167",exchangeTime:"\u4EA4\u6613\u6240\u65F6\u95F4",noChangePct:"\u6682\u65E0\u6DA8\u8DCC\u6570\u636E",typeAShare:"A\u80A1",typeHkStock:"\u6E2F\u80A1",typeUsStock:"\u7F8E\u80A1",typeAIndex:"A\u6307",typeHkIndex:"\u6E2F\u6307",typeUsIndex:"\u7F8E\u6307",kindStock:"\u80A1\u7968",kindIndex:"\u6307\u6570",kindEtf:"ETF",remove:"\u79FB\u9664",more:"\u66F4\u591A",pin:"\u7F6E\u9876",holdingWeightLabel:"\u6301\u4ED3\u6BD4\u4F8B",holdingStepper:"\u6301\u4ED3\u6BD4\u4F8B\uFF08\u6BCF\u6863 10 \u4E2A\u767E\u5206\u70B9\uFF09",holdingStepUp:"\u589E\u52A0\u6301\u4ED3\u6BD4\u4F8B",holdingStepDown:"\u51CF\u5C11\u6301\u4ED3\u6BD4\u4F8B",holdingName:"\u6301\u4ED3",predict:"\u9884\u6D4B",predictTip:"AI\u9884\u6D4B",review:"\u590D\u76D8",reviewTip:"AI\u590D\u76D8",predictPromptPrefix:"\u8BF7\u9884\u6D4B ",predictPromptSuffix:"\uFF1A\u672A\u6765 5 \u4E2A\u4EA4\u6613\u65E5\u7684\u8D70\u52BF\u4E0E\u5173\u952E\u70B9\u4F4D\uFF0C\u8BF4\u660E\u4F9D\u636E\uFF0C\u5E76\u7ED9\u51FA\u5224\u65AD\u7684\u4E0D\u786E\u5B9A\u6027\u3002",reviewPromptPrefix:"\u8BF7\u590D\u76D8 ",reviewPromptSuffix:"\uFF1A\u4ECA\u65E5\u8D70\u52BF\u4E0E\u91CF\u4EF7\u3001\u8FD1 20 \u65E5\u8D8B\u52BF\u3001\u57FA\u7840\u9762\u3001\u6D88\u606F\u9762\uFF0C\u7ED9\u51FA\u7ED3\u8BBA\u548C\u5FC5\u8981\u98CE\u9669\u8BC4\u4F30\u3002",searching:"\u641C\u7D22\u4E2D\u2026",composingHint:"\u8F93\u5165\u5B8C\u6210\u540E\u81EA\u52A8\u641C\u7D22",clearInput:"\u6E05\u7A7A\u8F93\u5165",confirmTitle:"\u786E\u8BA4\u79FB\u9664\uFF1F",confirmDescPrefix:"\u786E\u5B9A\u5C06 ",confirmDescSuffix:" \u4ECE\u81EA\u9009\u4E2D\u79FB\u9664\u5417\uFF1F",confirmCancel:"\u53D6\u6D88",confirmOk:"\u786E\u8BA4\u79FB\u9664",truncated:"\u6CA1\u6709\u66F4\u591A\uFF0C\u8BF7\u8F93\u5165\u51C6\u786E\u7684\u8BC1\u5238\u4EE3\u7801\u6216\u540D\u79F0\u3002",filterAll:"\u5168\u90E8",filterLabel:"\u6309\u5E02\u573A\u7B5B\u9009\u5019\u9009",filterNoHit:"\u8FD9\u4E2A\u5E02\u573A\u4E0B\u6CA1\u6709\u5339\u914D\u7684\u6807\u7684\u3002",noHit:"\u6CA1\u6709\u5339\u914D\u7684\u6807\u7684\uFF08A\u80A1 / \u6E2F\u80A1 / \u7F8E\u80A1\uFF0C\u542B\u6307\u6570\u4E0E\u573A\u5185\u57FA\u91D1\uFF09\u3002","error.invalid_query":"\u8F93\u5165\u4E0D\u88AB\u63A5\u53D7","error.not_found":"\u6CA1\u6709\u627E\u5230\u8BE5\u6807\u7684","error.ambiguous":"\u547D\u4E2D\u591A\u6761\uFF0C\u8BF7\u4ECE\u5019\u9009\u91CC\u9009\u4E00\u6761","error.list_full":"\u81EA\u9009\u80A1\u6700\u591A {max} \u6761\uFF0C\u5148\u5220\u4E00\u6761\u518D\u52A0","error.list_full_noMax":"\u81EA\u9009\u80A1\u5DF2\u8FBE\u4E0A\u9650\uFF0C\u5148\u5220\u4E00\u6761\u518D\u52A0","error.credential_missing":"\u672A\u914D\u7F6E Fuyao \u5BC6\u94A5\uFF1A\u5728\u300C\u63D2\u4EF6\u300D\u9875\u7684 Capital \u6A21\u5F0F\u5361\u7247\u91CC\u586B API Key\uFF08\u53EA\u5F71\u54CD A \u80A1\u90A3\u4E00\u8DEF\uFF0C\u6E2F\u7F8E\u80A1\u7167\u5E38\u7528\uFF09","error.rate_limited":"\u884C\u60C5\u670D\u52A1\u9650\u6D41\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5","error.fuyao_unavailable":"A \u80A1\u884C\u60C5\u6682\u65F6\u53D6\u4E0D\u5230\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5","error.tencent_unavailable":"\u6E2F\u7F8E\u80A1\u884C\u60C5\u6682\u65F6\u53D6\u4E0D\u5230\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5","error.quote_unavailable":"\u8BE5\u6807\u7684\u6CA1\u6709\u53EF\u7528\u62A5\u4EF7","error.refresh_timeout":"\u5237\u65B0\u8D85\u65F6\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5","error.store_unavailable":"\u81EA\u9009\u80A1\u5B58\u50A8\u4E0D\u53EF\u7528","error.unauthorized":"\u767B\u5F55\u72B6\u6001\u5DF2\u5931\u6548\uFF1A\u8BF7\u5148\u56DE\u5230\u5BBF\u4E3B\u7A97\u53E3\u91CD\u65B0\u767B\u5F55",errorSuffix:"\uFF08\u5176\u4ED6\u6807\u7684\u4ECD\u662F\u4E0A\u4E00\u6B21\u6210\u529F\u5FEB\u7167\uFF09","partial.a-share":"A \u80A1\u68C0\u7D22\u4E0D\u53EF\u7528\uFF1A","partial.hk":"\u6E2F\u80A1\u68C0\u7D22\u4E0D\u53EF\u7528\uFF1A","partial.us":"\u7F8E\u80A1\u68C0\u7D22\u4E0D\u53EF\u7528\uFF1A"},Mt={"command.label":"Watchlist","command.description":"Add / view / remove watched symbols",title:"Watchlist",close:"Close",searchPlaceholder:"Symbol code or name \u2014 A-share / HK / US",add:"Add",added:"Added",refreshing:"Refreshing\u2026",refresh:"Refresh quotes",loading:"Loading list\u2026",empty:"No symbols yet \u2014 use the input above to add one.",colName:"Symbol",colQuote:"Last / change",colAction:"Actions",updated:"Updated",notRefreshed:"Not refreshed",stale:"last snapshot",exchangeTime:"exchange time",noChangePct:"No change data yet",typeAShare:"A-Share",typeHkStock:"HK",typeUsStock:"US",typeAIndex:"A-Index",typeHkIndex:"HK-Index",typeUsIndex:"US-Index",kindStock:"stock",kindIndex:"index",kindEtf:"ETF",remove:"Remove",more:"More",pin:"Pin to top",holdingWeightLabel:"Holding weight",holdingStepper:"Holding weight, in steps of 10 percentage points",holdingStepUp:"Increase holding weight",holdingStepDown:"Decrease holding weight",holdingName:"Holding",predict:"Predict",predictTip:"AI prediction",review:"Review",reviewTip:"AI review",predictPromptPrefix:"Predict ",predictPromptSuffix:" over the next 5 sessions: the likely path and key levels, the evidence behind the call, and how uncertain it is.",reviewPromptPrefix:"Review ",reviewPromptSuffix:" with today's trend and volume, the last 20 sessions, fundamental, news, then a conclusion and the necessary risks analysis.",searching:"Searching\u2026",composingHint:"Search runs when you finish typing",clearInput:"Clear input",confirmTitle:"Remove this symbol?",confirmDescPrefix:"Remove ",confirmDescSuffix:" from your watchlist?",confirmCancel:"Cancel",confirmOk:"Remove",truncated:"No more candidates \u2014 enter an accurate code or name.",filterAll:"All",filterLabel:"Filter candidates by market",filterNoHit:"No matching symbol in this market.",noHit:"No matching symbol (A-share / HK / US, including indices and listed funds).","error.invalid_query":"Input not accepted","error.not_found":"Symbol not found","error.ambiguous":"Multiple hits \u2014 pick one candidate","error.list_full":"Watchlist holds at most {max} symbols \u2014 remove one first","error.list_full_noMax":"Watchlist is full \u2014 remove one first","error.credential_missing":"No Fuyao API key: set it on the Capital card in the Plugins page (A-share quotes only \u2014 HK and US keep working)","error.rate_limited":"Quote service is rate limited \u2014 try again later","error.fuyao_unavailable":"A-share quotes unavailable \u2014 try again later","error.tencent_unavailable":"HK / US quotes unavailable \u2014 try again later","error.quote_unavailable":"No quote for this symbol","error.refresh_timeout":"Refresh timed out \u2014 try again later","error.store_unavailable":"Watchlist storage unavailable","error.unauthorized":"Session expired \u2014 sign back in to the host first",errorSuffix:" (other symbols still show their last good snapshot)","partial.a-share":"A-share search unavailable: ","partial.hk":"HK search unavailable: ","partial.us":"US search unavailable: "},Ot={"a-share":"typeAShare","hk-stock":"typeHkStock","us-stock":"typeUsStock","a-share-index":"typeAIndex","hk-index":"typeHkIndex","us-index":"typeUsIndex","fund-etf":"typeAShare"},Ft={"a-share":"kindStock","hk-stock":"kindStock","us-stock":"kindStock","a-share-index":"kindIndex","hk-index":"kindIndex","us-index":"kindIndex","fund-etf":"kindEtf"};function Lt(e,a){let t=Ot[e];return t===void 0?String(e??""):a(t)}function jt(e,a){let t=Ft[e];return t===void 0?String(e??""):a(t)}var Dt=/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F-\u009F\u00AD\u200B-\u200F\u2028\u2029\u202A-\u202E\u2060-\u2064\u2066-\u2069\uFEFF]/gu;function T(e){return String(e??"").replace(Dt,"")}function v(e){return Array.isArray(e)?e.map(a=>a===null||typeof a!="object"?a:{...a,name:T(a.name)}):e}var Ut={"a-share":"capital-watchlist-tag-cn","a-share-index":"capital-watchlist-tag-cn","fund-etf":"capital-watchlist-tag-cn","hk-stock":"capital-watchlist-tag-hk","hk-index":"capital-watchlist-tag-hk","us-stock":"capital-watchlist-tag-us","us-index":"capital-watchlist-tag-us"},B=[{id:"all"},{id:"cn",label:"CN"},{id:"hk",label:"HK"},{id:"us",label:"US"}],U=e=>e.exchange==="HK"?"hk":e.exchange==="US"?"us":"cn",qt=`
9
9
  /* \u5BBD 420 / \u5706\u89D2 18 / \u65E0\u5185\u8FB9\u8DDD\uFF08\u5185\u8FB9\u8DDD\u4F4F\u5728\u5404\u6BB5\u81EA\u5DF1\u5934\u4E0A\uFF0C\u597D\u8BA9\u8868\u5934\u4E0E\u5206\u9694\u7EBF\u5BF9\u9F50\uFF09\u3002
10
10
  \u9650\u9AD8\u6309\u5B98\u65B9\u53E3\u5F84\u8D70 max-height: 100%\uFF08\u5BF9 .root \u7684 padding box\uFF09\uFF0C\u4E0D\u81EA\u5DF1\u7B97 vh\u3002 */
11
11
  .capital-watchlist-dialog.capital-watchlist-dialog { width: min(420px, 92vw); max-height: 100%; padding: 0; gap: 0; border-radius: 18px; }
@@ -259,8 +259,8 @@ window.__ModuleLoader__.load({
259
259
  \u6BD4\u5217\u8868\u5185\u5BB9\u76D2\u5BBD 16px\u2014\u2014\u90A3 16px \u5C31\u662F\u4E0A\u9762\u90A3\u6761\u6A2A\u5411\u6EDA\u52A8\u6761\u7684\u53E6\u4E00\u534A\u3002
260
260
  \u9009\u62E9\u5668\u6839\u5728\u6211\u4EEC\u81EA\u5DF1\u6302\u5728 portal \u5217\u8868\u4E0A\u7684\u7C7B\uFF0C\u6240\u4EE5\u591F\u5F97\u7740\uFF08\u540E\u4EE3\u94FE\u6CA1\u6709\u79BB\u5F00\u8FD9\u5F20\u5217\u8868\uFF09\u3002 */
261
261
  .capital-watchlist-rows button { box-sizing: border-box; }
262
- `;function Qt(){let e=globalThis.document;if(!e||typeof e.createElement!="function"||e.querySelector(`style[data-${D}]`))return;let a=e.createElement("style");a.setAttribute(`data-${D}`,""),a.textContent=qt;let t=e.head??e.body;if(!(t===void 0||typeof t.appendChild!="function"))return t.appendChild(a),()=>a.remove()}async function w(e,{query:a,body:t,signal:s}={}){let i=a!==void 0?`${j}${e}?${a}`:`${j}${e}`,d=t===void 0?{method:"GET",cache:"no-store",credentials:"same-origin",signal:s}:{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t),credentials:"same-origin",signal:s},n=await fetch(i,d),c=await n.text(),o={};try{o=c.length>0?JSON.parse(c):{}}catch{o={}}if(n.ok===!0&&o.ok===!0)return o;let p=typeof o.code=="string"&&o.code.length>0?o.code:n.status===401||n.status===403?"unauthorized":"fuyao_unavailable",h=new Error(p);throw h.code=p,h.candidates=o.candidates,h.limit=o.limit,h}var q=()=>({open:!1,loading:!1,refreshing:!1,searching:!1,items:[],candidates:[],truncated:!1,marketFilter:"all",query:"",dropdownOpen:!1,rowMenu:null,pendingRemove:null,refreshed_at:null,error:null,searchError:null,searchPartial:null,addError:null,loadError:null,failures:{},composing:!1,pendingSearch:!1}),E=class{constructor(){this.store=xt(q()),this.searchController=null,this.timer=null,this.pending=null,this.lastQuery=null,this.holdingOps=new Map}get state(){return this.store}get snapshot(){return this.store.getSnapshot()}patch(a){this.store.update(t=>Object.assign(t,a))}open(){this.patch({...q(),open:!0,loading:!0}),this.load().then(()=>this.refresh(),()=>this.patch({loading:!1}))}close(){this.timer!==null&&clearTimeout(this.timer),this.searchController!==null&&this.searchController.abort(),this.lastQuery=null,this.patch({open:!1,rowMenu:null,composing:!1,pendingSearch:!1}),this.holdingOps.clear()}async load(){try{let a=await w("/list");this.holdingOps.clear(),this.patch({items:y(a.items)??[],seeded_at:a.seeded_at,loading:!1,loadError:null})}catch(a){throw this.patch({loading:!1,loadError:{code:a.code??"fuyao_unavailable"}}),a}}refresh(){if(this.pending!==null)return this.pending;this.patch({refreshing:!0});let a=w("/refresh",{body:{}}).then(t=>{let s={};for(let n of t.failures??[])s[n.thscode]=n.code;let i=y(t.items),d=i??this.snapshot.items;i!==null&&this.holdingOps.clear(),this.patch({items:d,refreshed_at:t.refreshed_at??this.snapshot.refreshed_at,failures:s,error:t.error?{code:t.error.code,partial:d.length>0&&d.some(n=>s[n.thscode]===void 0)}:null})}).catch(t=>{this.patch({error:{code:t.code??"fuyao_unavailable",partial:this.snapshot.items.some(s=>s.quote!==null)}})}).finally(()=>{this.patch({refreshing:!1}),this.pending=null});return this.pending=a,a}onQueryChange(a,t){let s=a.trim(),i=t===void 0?this.snapshot.composing===!0:t===!0;if(this.patch({query:a,searchError:null,composing:i,dropdownOpen:s.length>0}),this.timer!==null&&clearTimeout(this.timer),s.length===0){this.searchController!==null&&this.searchController.abort(),this.lastQuery=null,this.patch({candidates:[],truncated:!1,searching:!1,pendingSearch:!1});return}s===this.lastQuery&&this.snapshot.pendingSearch===!1||(this.patch({candidates:[],truncated:!1,pendingSearch:!i}),i!==!0&&(this.timer=setTimeout(()=>this.search(s),Ht)))}beginComposition(){this.timer!==null&&clearTimeout(this.timer),this.patch({composing:!0})}endComposition(a){this.onQueryChange(a,!1)}hideDropdown(){this.patch({dropdownOpen:!1})}setMarketFilter(a){B.some(t=>t.id===a)&&this.patch({marketFilter:a})}toggleRowMenu(a){this.patch({rowMenu:this.snapshot.rowMenu===a?null:a})}closeRowMenu(){this.snapshot.rowMenu!==null&&this.patch({rowMenu:null})}setPendingRemove(a){this.patch({pendingRemove:a??null})}replaceRow(a){let[t]=y([a]);t===void 0||typeof t?.thscode!="string"||this.patch({items:this.snapshot.items.map(s=>s.thscode===t.thscode?t:s)})}async search(a){this.lastQuery=a,this.searchController!==null&&this.searchController.abort();let t=new AbortController;this.searchController=t,this.patch({searching:!0,searchError:null,searchPartial:null});let s=()=>this.snapshot.query.trim()===a;try{let i=await w("/search",{query:`q=${encodeURIComponent(a)}`,signal:t.signal});if(!s()){this.patch({searching:!1});return}this.patch({candidates:y(i.items)??[],truncated:i.truncated===!0,searching:!1,pendingSearch:!1,searchPartial:Array.isArray(i.partial)&&i.partial.length>0?i.partial:null})}catch(i){if(i.name==="AbortError"||(this.lastQuery===a&&(this.lastQuery=null),!s()))return;this.patch({candidates:[],truncated:!1,searching:!1,pendingSearch:!1,searchError:{code:i.code??"fuyao_unavailable"},searchPartial:null})}}async add(a){try{await w("/add",{body:{thscode:a.thscode}})}catch(s){this.patch({addError:{code:s.code??"fuyao_unavailable",candidates:s.candidates,limit:s.limit}}),s.candidates!==void 0&&this.patch({candidates:s.candidates,truncated:!1});return}this.patch({addError:null,candidates:this.snapshot.candidates.map(s=>s.thscode===a.thscode?{...s,in_list:!0}:s)}),await this.load().catch(()=>{}),await this.refresh();let t=this.snapshot.items.find(s=>s.thscode===a.thscode);t!==void 0&&t.quote===null&&this.snapshot.failures[a.thscode]===void 0&&await this.refresh()}async remove(a){let t=this.snapshot.items;this.patch({items:t.filter(s=>s.thscode!==a),rowMenu:null});try{await w("/remove",{body:{thscode:a}}),this.snapshot.addError?.code==="list_full"&&this.patch({addError:null})}catch{this.patch({items:t})}}async pin(a){let t=this.snapshot.items,s=t.find(i=>i.thscode===a);if(s!==void 0){this.patch({items:[s,...t.filter(i=>i.thscode!==a)],rowMenu:null});try{let i=await w("/pin",{body:{thscode:a}});Array.isArray(i.items)&&this.patch({items:y(i.items)})}catch{let i=this.snapshot.items,d=t.map(c=>i.find(o=>o.thscode===c.thscode)).filter(Boolean),n=new Set(d.map(c=>c.thscode));this.patch({items:[...d,...i.filter(c=>!n.has(c.thscode))]})}}}async writeHolding(a,t,s){let i=this.snapshot.items.find(o=>o.thscode===a);if(i===void 0)return;let d=this.holdingOps.get(a)??{seq:0,baseline:i};this.holdingOps.set(a,d);let n=++d.seq;this.patch({items:this.snapshot.items.map(o=>o.thscode===a?s(o):o)});let c=()=>this.holdingOps.get(a)!==d||d.seq!==n;try{let o=await w("/holding",{body:t});if(c())return;this.replaceRow(o.item),d.baseline=o.item??s(i),this.holdingOps.delete(a)}catch{if(c())return;this.replaceRow(d.baseline),this.holdingOps.delete(a)}}markHolding(a,t){return this.writeHolding(a,{thscode:a,weight_pct:t},s=>({...s,holding:{weight_pct:t,marked_at:Date.now()}}))}clearHolding(a){return this.writeHolding(a,{thscode:a,clear:!0},t=>{let s={...t};return delete s.holding,s})}stepHolding(a,t){let s=this.snapshot.items,i=s.find(n=>n.thscode===a)?.holding?.weight_pct;if(typeof i!="number"&&t<0)return;let d=Math.min(W(s,a),Math.max(0,(typeof i=="number"?i:0)+t));if(d!==i)return this.markHolding(a,d)}async copyToClipboard(){let a=this.snapshot.items.map(t=>[t.thscode,T(t.name),t.asset_type,t.quote?.price??"",t.quote?.change_pct??"",t.quote?.captured_at??""].join(" ")).join(`
263
- `);return await navigator.clipboard.writeText(a),a}dispose(){this.timer!==null&&clearTimeout(this.timer),this.searchController!==null&&this.searchController.abort()}};function K(e){if(typeof e!="number"||!Number.isFinite(e))return"";let a=new Date(e),t=s=>String(s).padStart(2,"0");return`${t(a.getMonth()+1)}-${t(a.getDate())} ${t(a.getHours())}:${t(a.getMinutes())}`}function Q({assetType:e,t:a}){return l("span",{className:`capital-watchlist-tag ${Ut[e]??"capital-watchlist-tag-cn"}`},Lt(e,a))}function Wt(e,a,t){let s=T(e.name);return`${a(`${t}PromptPrefix`)}${s} (${e.thscode} \xB7 ${jt(e.asset_type,a)})${a(`${t}PromptSuffix`)}`}function Bt({quote:e,failureCode:a,refreshing:t,t:s}){let i=a!==void 0;if(e==null)return t===!0?l("div",{className:"capital-watchlist-quote"},l("span",{className:"capital-watchlist-skeleton capital-watchlist-skeleton-price"}),l("span",{className:"capital-watchlist-skeleton capital-watchlist-skeleton-change"})):i?l("div",{className:"capital-watchlist-quote",title:s(`error.${a}`)},l("div",{className:"capital-watchlist-price capital-watchlist-quotefailed"},"\u2014")):l("div",{className:"capital-watchlist-quote"},l("div",{className:"capital-watchlist-price"},s("notRefreshed")));let d=typeof e.change_pct=="number"&&Number.isFinite(e.change_pct),n=d?`${e.change_pct>0?"+":""}${e.change_pct.toFixed(2)}%`:"\u2014",c=i?"capital-watchlist-stale":d?e.change_pct>0?"capital-watchlist-up":e.change_pct<0?"capital-watchlist-down":"capital-watchlist-flat":"capital-watchlist-nodata",o=typeof e.source_time=="string"&&e.source_time.length>0?`${s("exchangeTime")} ${e.source_time}`:"",p=[];return i?p.push(`${s(`error.${a}`)} \xB7 ${s("stale")} ${K(e.captured_at)}`):d||p.push(s("noChangePct")),o.length>0&&p.push(o),l("div",{className:"capital-watchlist-quote",title:p.length===0?void 0:p.join(" \xB7 ")},l("div",{className:i?"capital-watchlist-price capital-watchlist-stale":"capital-watchlist-price"},e.price.toFixed(2)),l("div",{className:`capital-watchlist-change ${c}`},n))}function Kt(e,a){if(a.code!=="list_full")return e(`error.${a.code}`);let t=a.limit;return typeof t!="number"||!Number.isFinite(t)?e("error.list_full_noMax"):e("error.list_full").replace("{max}",String(t))}function Yt(e,a){let t=e?.weight_pct;return t==null?a("holdingName"):`${a("holdingName")} ${t}%`}function Gt(e,a){let t=`${e.name} ${e.ticker}`;return e.holding===null||e.holding===void 0?t:`${t} \xB7 ${Yt(e.holding,a)}`}function Xt({useDialog:e,surface:a,t,inputActions:s}){let i=e(r=>r),[d,n]=M(!1),[c,o]=M(null),p=i.pendingRemove??null;if(bt(()=>()=>a.dispose(),[a]),!i.open)return null;let h=i.dropdownOpen===!0,g=p!==null,Y=r=>{if(r.key==="Escape"){if(g){r.stopPropagation(),a.setPendingRemove(null);return}h&&(r.stopPropagation(),a.hideDropdown())}},G=r=>{if(!h)return;let m=r.relatedTarget;m!=null&&r.currentTarget?.contains?.(m)===!0||a.hideDropdown()},b=i.error,X=b==null?null:l("p",{className:"capital-watchlist-notice",role:"alert","data-code":b.code},`${t(`error.${b.code}`)}${b.partial===!0?t("errorSuffix"):""}`),A=(r,m)=>{s.insertText(Wt(r,t,m),s.captureInsertion())===!0&&a.close()},v=i.marketFilter==="all"?i.candidates:i.candidates.filter(r=>U(r)===i.marketFilter),$={all:i.candidates.length,cn:0,hk:0,us:0};for(let r of i.candidates)$[U(r)]+=1;let J=i.candidates.length===0?null:l("div",{className:"capital-watchlist-filter",role:"group","aria-label":t("filterLabel")},B.map(r=>l("button",{key:r.id,type:"button",className:"capital-watchlist-filterbtn","aria-pressed":i.marketFilter===r.id,onClick:()=>a.setMarketFilter(r.id)},l("span",{className:"capital-watchlist-filterlabel"},r.id==="all"?t("filterAll"):r.label),l("span",{className:"capital-watchlist-filtercount"},String($[r.id]))))),V=h?l("div",{className:"capital-watchlist-dropdown","aria-label":t("title"),"data-menu-material":"translucent"},J,l("div",{className:"capital-watchlist-options",role:"listbox","aria-label":t("title")},v.map(r=>l("button",{key:r.thscode,type:"button",role:"option",className:"capital-watchlist-option",title:r.name,"aria-disabled":r.in_list===!0||c===r.thscode,onClick:()=>{r.in_list===!0||c===r.thscode||(n(!0),o(r.thscode),a.add(r).finally(()=>{n(!1),o(null)}))}},l("span",{className:"capital-watchlist-optionmain"},l("span",{className:"capital-watchlist-optionname"},r.name),l("span",{className:"capital-watchlist-codeline"},l("span",{className:"capital-watchlist-optioncode"},r.thscode),l(Q,{assetType:r.asset_type,t}))),l("span",{className:"capital-watchlist-addbtn","data-state":r.in_list===!0?"added":"idle"},r.in_list===!0?t("added"):t("add")))),i.truncated===!0&&v.length>0?l("div",{className:"capital-watchlist-hint capital-watchlist-endhint"},t("truncated")):null),i.composing===!0?l("div",{className:"capital-watchlist-hint"},t("composingHint")):i.searching===!0||i.pendingSearch===!0?l("div",{className:"capital-watchlist-hint"},t("searching")):i.searchError!==null&&i.searchError!==void 0?l("div",{className:"capital-watchlist-hint capital-watchlist-searcherror",role:"alert","data-code":i.searchError.code},t(`error.${i.searchError.code}`)):i.candidates.length===0?l("div",{className:"capital-watchlist-hint"},t("noHit")):v.length===0?l("div",{className:"capital-watchlist-hint","data-filter":i.marketFilter},t("filterNoHit")):null,...(i.searchPartial??[]).map(r=>l("div",{key:`partial-${r.market}`,className:"capital-watchlist-hint capital-watchlist-searcherror",role:"status","data-market":r.market,"data-code":r.code},`${t(`partial.${r.market}`)}${t(`error.${r.code}`)}`))):null,Z=i.items.length===0?null:l("div",{className:"capital-watchlist-grid capital-watchlist-head"},l("span",null,t("colName")),l("span",{className:"capital-watchlist-quote"},t("colQuote")),l("span",{className:"capital-watchlist-headaction"},t("colAction"))),tt=i.loadError!==null&&i.loadError!==void 0?l("p",{className:"capital-watchlist-empty capital-watchlist-loaderror",role:"alert","data-code":i.loadError.code},t(`error.${i.loadError.code}`)):l("p",{className:"capital-watchlist-empty"},t("empty")),at=i.loading?l("p",{className:"capital-watchlist-empty"},t("loading")):i.items.length===0?tt:l("div",{className:h?"capital-watchlist-list capital-watchlist-list-open":"capital-watchlist-list"},i.items.map((r,m)=>{let x=r.holding!==null&&r.holding!==void 0,u=r.holding?.weight_pct,it=F(r)||x,k=W(i.items,r.thscode),lt=!x||u===null||u===void 0||u<=0,rt=(typeof u=="number"?u:0)+C>k;return l("div",{key:r.thscode,className:"capital-watchlist-grid capital-watchlist-row","data-thscode":r.thscode},l("span",{className:"capital-watchlist-namewrap"},l("span",{className:x?"capital-watchlist-name capital-watchlist-name-held":"capital-watchlist-name",title:Gt(r,t)},r.name),l("span",{className:"capital-watchlist-codeline"},l("span",{className:"capital-watchlist-code"},r.ticker),l(Q,{assetType:r.asset_type,t}))),l(Bt,{quote:r.quote,failureCode:i.failures[r.thscode],refreshing:i.refreshing,t}),l("span",{className:"capital-watchlist-rowactions"},l("button",{type:"button",className:"capital-watchlist-predict",disabled:d,title:t("predictTip"),"aria-label":`${t("predict")} ${r.name}`,onClick:()=>A(r,"predict")},l(Nt,{size:14})),l("button",{type:"button",className:"capital-watchlist-review",disabled:d,title:t("reviewTip"),"aria-label":`${t("review")} ${r.name}`,onClick:()=>A(r,"review")},l(St,{size:14})),l(At,{open:i.rowMenu===r.thscode,anchor:l("button",{type:"button",className:"capital-watchlist-more",disabled:d,title:t("more"),"aria-label":`${t("more")} ${r.name}`,"aria-haspopup":"menu","aria-expanded":i.rowMenu===r.thscode,onClick:()=>a.toggleRowMenu(r.thscode)},l(kt,{size:14})),items:[{id:"pin",label:t("pin"),icon:l(_t,{size:14}),disabled:m===0}],children:[...it?[l("div",{key:"holding-check",role:"group","aria-label":t("holdingName"),className:"capital-watchlist-checkrow"},l("span",{className:"capital-watchlist-checkicon","aria-hidden":"true"},l(vt,{size:14})),l("span",{className:"capital-watchlist-checklabel"},t("holdingName")),l(It,{checked:x,disabled:d,label:t("holdingName"),onChange:N=>N?a.markHolding(r.thscode,null):a.clearHolding(r.thscode)}))]:[],...x&&F(r)?[l("div",{key:"holding-step",className:"capital-watchlist-stepper",role:"group","aria-label":t("holdingStepper")},l("span",{className:"capital-watchlist-stepperlabel"},t("holdingWeightLabel")),l("span",{className:"capital-watchlist-stepperline"},l("button",{type:"button",className:"capital-watchlist-stepperbtn","aria-label":t("holdingStepDown"),disabled:lt,onClick:()=>a.stepHolding(r.thscode,-C)},"\u2212"),l("span",{className:typeof u=="number"?"capital-watchlist-stepperreadout":"capital-watchlist-stepperreadout capital-watchlist-stepperplaceholder",role:"status"},typeof u=="number"?`${u}%`:`0~${k}`),l("button",{type:"button",className:"capital-watchlist-stepperbtn","aria-label":t("holdingStepUp"),title:`0~${k}`,disabled:rt,onClick:()=>a.stepHolding(r.thscode,C)},"+")))]:[],l($t,{key:"remove",danger:!0,separatorBefore:!0,icon:l(Tt,{size:14}),onSelect:()=>{a.closeRowMenu(),a.setPendingRemove(r)}},t("remove"))],onSelect:N=>{N==="pin"&&(a.closeRowMenu(),a.pin(r.thscode))},onClose:()=>a.closeRowMenu(),align:"end",portal:!0,listClassName:"capital-watchlist-rows",className:"capital-watchlist-actions"})))})),et=l("div",{className:g?"capital-watchlist-confirm capital-watchlist-confirm-open":"capital-watchlist-confirm","aria-hidden":g?void 0:"true"},l("div",{className:"capital-watchlist-confirmbox",role:g?"alertdialog":void 0,"aria-label":t("confirmTitle")},l("div",{className:"capital-watchlist-confirmtitle"},t("confirmTitle")),g?l("p",{className:"capital-watchlist-confirmdesc"},t("confirmDescPrefix"),l("strong",null,`${p.name} \xB7 ${p.ticker}`),t("confirmDescSuffix")):null,l("div",{className:"capital-watchlist-confirmactions"},l("button",{type:"button",className:"capital-watchlist-confirmbtn",onClick:()=>a.setPendingRemove(null)},t("confirmCancel")),l("button",{type:"button",className:"capital-watchlist-confirmbtn capital-watchlist-confirmdanger",onClick:()=>{let r=p;a.setPendingRemove(null),r!==null&&a.remove(r.thscode)}},t("confirmOk")))));return l(Pt,{open:!0,onClose:()=>a.close(),title:t("title"),headless:!0,shortcutModal:"watchlist",className:"capital-watchlist-dialog"},l("div",{className:"capital-watchlist-card",onKeyDown:Y},l("div",{className:"capital-watchlist-header"},l("h2",{className:"capital-watchlist-title"},t("title")),l("button",{type:"button",className:"capital-watchlist-close","aria-label":t("close"),onClick:()=>a.close()},l(O,{size:14}))),l("div",{className:"capital-watchlist-search",onBlur:G},l("div",{className:"capital-watchlist-field"},l("span",{className:"capital-watchlist-searchicon"},l(Et,{size:16})),l("input",{className:"capital-watchlist-input","data-modal-autofocus":!0,value:i.query,placeholder:t("searchPlaceholder"),onChange:r=>a.onQueryChange(r.target.value,r.isComposing),onCompositionStart:()=>a.beginComposition(),onCompositionEnd:r=>a.endComposition(r.target.value)}),i.query.length>0?l("button",{type:"button",className:"capital-watchlist-clear",title:t("clearInput"),"aria-label":t("clearInput"),onMouseDown:r=>r.preventDefault(),onClick:()=>a.onQueryChange("",!1)},l(O,{size:12})):null),V),i.addError!==null&&i.addError!==void 0?l("p",{className:"capital-watchlist-adderror",role:"status","data-code":i.addError.code},Kt(t,i.addError)):null,Z,at,l("div",{className:"capital-watchlist-footer"},l("div",{className:"capital-watchlist-footcol"},l("button",{type:"button",className:"capital-watchlist-refresh",disabled:i.refreshing||d,onClick:()=>{a.refresh()}},l(Ct,{size:14}),i.refreshing?t("refreshing"):t("refresh")),X),l("span",{className:"capital-watchlist-updated"},`${t("updated")} ${i.refreshed_at===null||i.refreshed_at===void 0?t("notRefreshed"):K(i.refreshed_at)}`)),et))}function Jt(e){e.effect(Qt,`${f}: styles`),e.effect(()=>e.locale.register(_,{zh:zt,en:Mt}),`${f}: dictionaries`);let a=new Map,t=n=>{let c=a.get(n);return c===void 0&&(c=new E,a.set(n,c)),c};e.effect(()=>()=>{for(let n of a.values())n.dispose();a.clear()},`${f}: per-session surfaces`);let s=n=>{let o=e.sessions?.list?.getSnapshot?.().byId?.[n]?.projectionValues?.agentPreset;return typeof o=="string"?o:void 0},i=new Set,d=n=>{let c=s(n);return c!==void 0?c===Rt:(i.has(n)||(i.add(n),Promise.resolve(e.sessions?.refreshProjections?.(n)).catch(()=>{})),!1)};e.slots.inject(L,()=>e.slots.register({name:L,id:"capital-watchlist-dialog",order:3,locale:_,inject:n=>{let c=t(n);return{hooks:{dialog:c.state},surface:c}}},Xt)),e.inject(["commandUi"],n=>{let c=e.locale.bind(_);n.effect(()=>n.commandUi.register({name:"watchlist",label:()=>c("command.label"),description:()=>c("command.description"),icon:yt,available:o=>d(o.sessionId),ui:{kind:"action",run:o=>{t(o.sessionId).open()}}}),`${f}: /watchlist contribution`)}),e.logger?.info?.(`${f}: \u5BA2\u6237\u7AEF\u534A\u8FB9\u5DF2\u6302\u8F7D\uFF08/watchlist \u83DC\u5355\u884C + \u81EA\u9009\u80A1\u5F39\u7A97\uFF09`)}exports.name=f;exports.inject=["slots","locale","commandUi","sessions"];exports.apply=Jt;
262
+ `;function Qt(){let e=globalThis.document;if(!e||typeof e.createElement!="function"||e.querySelector(`style[data-${D}]`))return;let a=e.createElement("style");a.setAttribute(`data-${D}`,""),a.textContent=qt;let t=e.head??e.body;if(!(t===void 0||typeof t.appendChild!="function"))return t.appendChild(a),()=>a.remove()}async function w(e,{query:a,body:t,signal:s}={}){let i=a!==void 0?`${j}${e}?${a}`:`${j}${e}`,d=t===void 0?{method:"GET",cache:"no-store",credentials:"same-origin",signal:s}:{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify(t),credentials:"same-origin",signal:s},n=await fetch(i,d),c=await n.text(),o={};try{o=c.length>0?JSON.parse(c):{}}catch{o={}}if(n.ok===!0&&o.ok===!0)return o;let p=typeof o.code=="string"&&o.code.length>0?o.code:n.status===401||n.status===403?"unauthorized":"fuyao_unavailable",h=new Error(p);throw h.code=p,h.candidates=o.candidates,h.limit=o.limit,h}var q=()=>({open:!1,loading:!1,refreshing:!1,searching:!1,items:[],candidates:[],truncated:!1,marketFilter:"all",query:"",dropdownOpen:!1,rowMenu:null,pendingRemove:null,refreshed_at:null,error:null,searchError:null,searchPartial:null,addError:null,loadError:null,failures:{},composing:!1,pendingSearch:!1}),E=class{constructor(){this.store=xt(q()),this.searchController=null,this.timer=null,this.pending=null,this.lastQuery=null,this.holdingOps=new Map}get state(){return this.store}get snapshot(){return this.store.getSnapshot()}patch(a){this.store.update(t=>Object.assign(t,a))}open(){this.patch({...q(),open:!0,loading:!0}),this.load().then(()=>this.refresh(),()=>this.patch({loading:!1}))}close(){this.timer!==null&&clearTimeout(this.timer),this.searchController!==null&&this.searchController.abort(),this.lastQuery=null,this.patch({open:!1,rowMenu:null,composing:!1,pendingSearch:!1}),this.holdingOps.clear()}async load(){try{let a=await w("/list");this.holdingOps.clear(),this.patch({items:v(a.items)??[],seeded_at:a.seeded_at,loading:!1,loadError:null})}catch(a){throw this.patch({loading:!1,loadError:{code:a.code??"fuyao_unavailable"}}),a}}refresh(){if(this.pending!==null)return this.pending;this.patch({refreshing:!0});let a=w("/refresh",{body:{}}).then(t=>{let s={};for(let n of t.failures??[])s[n.thscode]=n.code;let i=v(t.items),d=i??this.snapshot.items;i!==null&&this.holdingOps.clear(),this.patch({items:d,refreshed_at:t.refreshed_at??this.snapshot.refreshed_at,failures:s,error:t.error?{code:t.error.code,partial:d.length>0&&d.some(n=>s[n.thscode]===void 0)}:null})}).catch(t=>{this.patch({error:{code:t.code??"fuyao_unavailable",partial:this.snapshot.items.some(s=>s.quote!==null)}})}).finally(()=>{this.patch({refreshing:!1}),this.pending=null});return this.pending=a,a}onQueryChange(a,t){let s=a.trim(),i=t===void 0?this.snapshot.composing===!0:t===!0;if(this.patch({query:a,searchError:null,composing:i,dropdownOpen:s.length>0}),this.timer!==null&&clearTimeout(this.timer),s.length===0){this.searchController!==null&&this.searchController.abort(),this.lastQuery=null,this.patch({candidates:[],truncated:!1,searching:!1,pendingSearch:!1});return}s===this.lastQuery&&this.snapshot.pendingSearch===!1||(this.patch({candidates:[],truncated:!1,pendingSearch:!i}),i!==!0&&(this.timer=setTimeout(()=>this.search(s),Ht)))}beginComposition(){this.timer!==null&&clearTimeout(this.timer),this.patch({composing:!0})}endComposition(a){this.onQueryChange(a,!1)}hideDropdown(){this.patch({dropdownOpen:!1})}setMarketFilter(a){B.some(t=>t.id===a)&&this.patch({marketFilter:a})}toggleRowMenu(a){this.patch({rowMenu:this.snapshot.rowMenu===a?null:a})}closeRowMenu(){this.snapshot.rowMenu!==null&&this.patch({rowMenu:null})}setPendingRemove(a){this.patch({pendingRemove:a??null})}replaceRow(a){let[t]=v([a]);t===void 0||typeof t?.thscode!="string"||this.patch({items:this.snapshot.items.map(s=>s.thscode===t.thscode?t:s)})}async search(a){this.lastQuery=a,this.searchController!==null&&this.searchController.abort();let t=new AbortController;this.searchController=t,this.patch({searching:!0,searchError:null,searchPartial:null});let s=()=>this.snapshot.query.trim()===a;try{let i=await w("/search",{query:`q=${encodeURIComponent(a)}`,signal:t.signal});if(!s()){this.patch({searching:!1});return}this.patch({candidates:v(i.items)??[],truncated:i.truncated===!0,searching:!1,pendingSearch:!1,searchPartial:Array.isArray(i.partial)&&i.partial.length>0?i.partial:null})}catch(i){if(i.name==="AbortError"||(this.lastQuery===a&&(this.lastQuery=null),!s()))return;this.patch({candidates:[],truncated:!1,searching:!1,pendingSearch:!1,searchError:{code:i.code??"fuyao_unavailable"},searchPartial:null})}}async add(a){try{await w("/add",{body:{thscode:a.thscode}})}catch(s){this.patch({addError:{code:s.code??"fuyao_unavailable",candidates:s.candidates,limit:s.limit}}),s.candidates!==void 0&&this.patch({candidates:s.candidates,truncated:!1});return}this.patch({addError:null,candidates:this.snapshot.candidates.map(s=>s.thscode===a.thscode?{...s,in_list:!0}:s)}),await this.load().catch(()=>{}),await this.refresh();let t=this.snapshot.items.find(s=>s.thscode===a.thscode);t!==void 0&&t.quote===null&&this.snapshot.failures[a.thscode]===void 0&&await this.refresh()}async remove(a){let t=this.snapshot.items;this.patch({items:t.filter(s=>s.thscode!==a),rowMenu:null});try{await w("/remove",{body:{thscode:a}}),this.snapshot.addError?.code==="list_full"&&this.patch({addError:null})}catch{this.patch({items:t})}}async pin(a){let t=this.snapshot.items,s=t.find(i=>i.thscode===a);if(s!==void 0){this.patch({items:[s,...t.filter(i=>i.thscode!==a)],rowMenu:null});try{let i=await w("/pin",{body:{thscode:a}});Array.isArray(i.items)&&this.patch({items:v(i.items)})}catch{let i=this.snapshot.items,d=t.map(c=>i.find(o=>o.thscode===c.thscode)).filter(Boolean),n=new Set(d.map(c=>c.thscode));this.patch({items:[...d,...i.filter(c=>!n.has(c.thscode))]})}}}async writeHolding(a,t,s){let i=this.snapshot.items.find(o=>o.thscode===a);if(i===void 0)return;let d=this.holdingOps.get(a)??{seq:0,baseline:i};this.holdingOps.set(a,d);let n=++d.seq;this.patch({items:this.snapshot.items.map(o=>o.thscode===a?s(o):o)});let c=()=>this.holdingOps.get(a)!==d||d.seq!==n;try{let o=await w("/holding",{body:t});if(c())return;this.replaceRow(o.item),d.baseline=o.item??s(i),this.holdingOps.delete(a)}catch{if(c())return;this.replaceRow(d.baseline),this.holdingOps.delete(a)}}markHolding(a,t){return this.writeHolding(a,{thscode:a,weight_pct:t},s=>({...s,holding:{weight_pct:t,marked_at:Date.now()}}))}clearHolding(a){return this.writeHolding(a,{thscode:a,clear:!0},t=>{let s={...t};return delete s.holding,s})}stepHolding(a,t){let s=this.snapshot.items,i=s.find(n=>n.thscode===a)?.holding?.weight_pct;if(typeof i!="number"&&t<0)return;let d=Math.min(W(s,a),Math.max(0,(typeof i=="number"?i:0)+t));if(d!==i)return this.markHolding(a,d)}async copyToClipboard(){let a=this.snapshot.items.map(t=>[t.thscode,T(t.name),t.asset_type,t.quote?.price??"",t.quote?.change_pct??"",t.quote?.captured_at??""].join(" ")).join(`
263
+ `);return await navigator.clipboard.writeText(a),a}dispose(){this.timer!==null&&clearTimeout(this.timer),this.searchController!==null&&this.searchController.abort()}};function K(e){if(typeof e!="number"||!Number.isFinite(e))return"";let a=new Date(e),t=s=>String(s).padStart(2,"0");return`${t(a.getMonth()+1)}-${t(a.getDate())} ${t(a.getHours())}:${t(a.getMinutes())}`}function Q({assetType:e,t:a}){return l("span",{className:`capital-watchlist-tag ${Ut[e]??"capital-watchlist-tag-cn"}`},Lt(e,a))}function Wt(e,a,t){let s=T(e.name);return`${a(`${t}PromptPrefix`)}${s} (${e.thscode} \xB7 ${jt(e.asset_type,a)})${a(`${t}PromptSuffix`)}`}function Bt({quote:e,failureCode:a,refreshing:t,t:s}){let i=a!==void 0;if(e==null)return t===!0?l("div",{className:"capital-watchlist-quote"},l("span",{className:"capital-watchlist-skeleton capital-watchlist-skeleton-price"}),l("span",{className:"capital-watchlist-skeleton capital-watchlist-skeleton-change"})):i?l("div",{className:"capital-watchlist-quote",title:s(`error.${a}`)},l("div",{className:"capital-watchlist-price capital-watchlist-quotefailed"},"\u2014")):l("div",{className:"capital-watchlist-quote"},l("div",{className:"capital-watchlist-price"},s("notRefreshed")));let d=typeof e.change_pct=="number"&&Number.isFinite(e.change_pct),n=d?`${e.change_pct>0?"+":""}${e.change_pct.toFixed(2)}%`:"\u2014",c=i?"capital-watchlist-stale":d?e.change_pct>0?"capital-watchlist-up":e.change_pct<0?"capital-watchlist-down":"capital-watchlist-flat":"capital-watchlist-nodata",o=typeof e.source_time=="string"&&e.source_time.length>0?`${s("exchangeTime")} ${e.source_time}`:"",p=[];return i?p.push(`${s(`error.${a}`)} \xB7 ${s("stale")} ${K(e.captured_at)}`):d||p.push(s("noChangePct")),o.length>0&&p.push(o),l("div",{className:"capital-watchlist-quote",title:p.length===0?void 0:p.join(" \xB7 ")},l("div",{className:i?"capital-watchlist-price capital-watchlist-stale":"capital-watchlist-price"},e.price.toFixed(2)),l("div",{className:`capital-watchlist-change ${c}`},n))}function Kt(e,a){if(a.code!=="list_full")return e(`error.${a.code}`);let t=a.limit;return typeof t!="number"||!Number.isFinite(t)?e("error.list_full_noMax"):e("error.list_full").replace("{max}",String(t))}function Yt(e,a){let t=e?.weight_pct;return t==null?a("holdingName"):`${a("holdingName")} ${t}%`}function Gt(e,a){let t=`${e.name} ${e.ticker}`;return e.holding===null||e.holding===void 0?t:`${t} \xB7 ${Yt(e.holding,a)}`}function Xt({useDialog:e,surface:a,t,inputActions:s}){let i=e(r=>r),[d,n]=M(!1),[c,o]=M(null),p=i.pendingRemove??null;if(bt(()=>()=>a.dispose(),[a]),!i.open)return null;let h=i.dropdownOpen===!0,g=p!==null,Y=r=>{if(r.key==="Escape"){if(g){r.stopPropagation(),a.setPendingRemove(null);return}h&&(r.stopPropagation(),a.hideDropdown())}},G=r=>{if(!h)return;let m=r.relatedTarget;m!=null&&r.currentTarget?.contains?.(m)===!0||a.hideDropdown()},b=i.error,X=b==null?null:l("p",{className:"capital-watchlist-notice",role:"alert","data-code":b.code},`${t(`error.${b.code}`)}${b.partial===!0?t("errorSuffix"):""}`),A=(r,m)=>{s.insertText(Wt(r,t,m),s.captureInsertion())===!0&&a.close()},y=i.marketFilter==="all"?i.candidates:i.candidates.filter(r=>U(r)===i.marketFilter),$={all:i.candidates.length,cn:0,hk:0,us:0};for(let r of i.candidates)$[U(r)]+=1;let J=i.candidates.length===0?null:l("div",{className:"capital-watchlist-filter",role:"group","aria-label":t("filterLabel")},B.map(r=>l("button",{key:r.id,type:"button",className:"capital-watchlist-filterbtn","aria-pressed":i.marketFilter===r.id,onClick:()=>a.setMarketFilter(r.id)},l("span",{className:"capital-watchlist-filterlabel"},r.id==="all"?t("filterAll"):r.label),l("span",{className:"capital-watchlist-filtercount"},String($[r.id]))))),V=h?l("div",{className:"capital-watchlist-dropdown","aria-label":t("title"),"data-menu-material":"translucent"},J,l("div",{className:"capital-watchlist-options",role:"listbox","aria-label":t("title")},y.map(r=>l("button",{key:r.thscode,type:"button",role:"option",className:"capital-watchlist-option",title:r.name,"aria-disabled":r.in_list===!0||c===r.thscode,onClick:()=>{r.in_list===!0||c===r.thscode||(n(!0),o(r.thscode),a.add(r).finally(()=>{n(!1),o(null)}))}},l("span",{className:"capital-watchlist-optionmain"},l("span",{className:"capital-watchlist-optionname"},r.name),l("span",{className:"capital-watchlist-codeline"},l("span",{className:"capital-watchlist-optioncode"},r.thscode),l(Q,{assetType:r.asset_type,t}))),l("span",{className:"capital-watchlist-addbtn","data-state":r.in_list===!0?"added":"idle"},r.in_list===!0?t("added"):t("add")))),i.truncated===!0&&y.length>0?l("div",{className:"capital-watchlist-hint capital-watchlist-endhint"},t("truncated")):null),i.composing===!0?l("div",{className:"capital-watchlist-hint"},t("composingHint")):i.searching===!0||i.pendingSearch===!0?l("div",{className:"capital-watchlist-hint"},t("searching")):i.searchError!==null&&i.searchError!==void 0?l("div",{className:"capital-watchlist-hint capital-watchlist-searcherror",role:"alert","data-code":i.searchError.code},t(`error.${i.searchError.code}`)):i.candidates.length===0?l("div",{className:"capital-watchlist-hint"},t("noHit")):y.length===0?l("div",{className:"capital-watchlist-hint","data-filter":i.marketFilter},t("filterNoHit")):null,...(i.searchPartial??[]).map(r=>l("div",{key:`partial-${r.market}`,className:"capital-watchlist-hint capital-watchlist-searcherror",role:"status","data-market":r.market,"data-code":r.code},`${t(`partial.${r.market}`)}${t(`error.${r.code}`)}`))):null,Z=i.items.length===0?null:l("div",{className:"capital-watchlist-grid capital-watchlist-head"},l("span",null,t("colName")),l("span",{className:"capital-watchlist-quote"},t("colQuote")),l("span",{className:"capital-watchlist-headaction"},t("colAction"))),tt=i.loadError!==null&&i.loadError!==void 0?l("p",{className:"capital-watchlist-empty capital-watchlist-loaderror",role:"alert","data-code":i.loadError.code},t(`error.${i.loadError.code}`)):l("p",{className:"capital-watchlist-empty"},t("empty")),at=i.loading?l("p",{className:"capital-watchlist-empty"},t("loading")):i.items.length===0?tt:l("div",{className:h?"capital-watchlist-list capital-watchlist-list-open":"capital-watchlist-list"},i.items.map((r,m)=>{let x=r.holding!==null&&r.holding!==void 0,u=r.holding?.weight_pct,it=F(r)||x,k=W(i.items,r.thscode),lt=!x||u===null||u===void 0||u<=0,rt=(typeof u=="number"?u:0)+C>k;return l("div",{key:r.thscode,className:"capital-watchlist-grid capital-watchlist-row","data-thscode":r.thscode},l("span",{className:"capital-watchlist-namewrap"},l("span",{className:x?"capital-watchlist-name capital-watchlist-name-held":"capital-watchlist-name",title:Gt(r,t)},r.name),l("span",{className:"capital-watchlist-codeline"},l("span",{className:"capital-watchlist-code"},r.ticker),l(Q,{assetType:r.asset_type,t}))),l(Bt,{quote:r.quote,failureCode:i.failures[r.thscode],refreshing:i.refreshing,t}),l("span",{className:"capital-watchlist-rowactions"},l("button",{type:"button",className:"capital-watchlist-predict",disabled:d,title:t("predictTip"),"aria-label":`${t("predict")} ${r.name}`,onClick:()=>A(r,"predict")},l(Nt,{size:14})),l("button",{type:"button",className:"capital-watchlist-review",disabled:d,title:t("reviewTip"),"aria-label":`${t("review")} ${r.name}`,onClick:()=>A(r,"review")},l(St,{size:14})),l(At,{open:i.rowMenu===r.thscode,anchor:l("button",{type:"button",className:"capital-watchlist-more",disabled:d,title:t("more"),"aria-label":`${t("more")} ${r.name}`,"aria-haspopup":"menu","aria-expanded":i.rowMenu===r.thscode,onClick:()=>a.toggleRowMenu(r.thscode)},l(kt,{size:14})),items:[{id:"pin",label:t("pin"),icon:l(_t,{size:14}),disabled:m===0}],children:[...it?[l("div",{key:"holding-check",role:"group","aria-label":t("holdingName"),className:"capital-watchlist-checkrow"},l("span",{className:"capital-watchlist-checkicon","aria-hidden":"true"},l(yt,{size:14})),l("span",{className:"capital-watchlist-checklabel"},t("holdingName")),l(It,{checked:x,disabled:d,label:t("holdingName"),onChange:N=>N?a.markHolding(r.thscode,null):a.clearHolding(r.thscode)}))]:[],...x&&F(r)?[l("div",{key:"holding-step",className:"capital-watchlist-stepper",role:"group","aria-label":t("holdingStepper")},l("span",{className:"capital-watchlist-stepperlabel"},t("holdingWeightLabel")),l("span",{className:"capital-watchlist-stepperline"},l("button",{type:"button",className:"capital-watchlist-stepperbtn","aria-label":t("holdingStepDown"),disabled:lt,onClick:()=>a.stepHolding(r.thscode,-C)},"\u2212"),l("span",{className:typeof u=="number"?"capital-watchlist-stepperreadout":"capital-watchlist-stepperreadout capital-watchlist-stepperplaceholder",role:"status"},typeof u=="number"?`${u}%`:`0~${k}`),l("button",{type:"button",className:"capital-watchlist-stepperbtn","aria-label":t("holdingStepUp"),title:`0~${k}`,disabled:rt,onClick:()=>a.stepHolding(r.thscode,C)},"+")))]:[],l($t,{key:"remove",danger:!0,separatorBefore:!0,icon:l(Tt,{size:14}),onSelect:()=>{a.closeRowMenu(),a.setPendingRemove(r)}},t("remove"))],onSelect:N=>{N==="pin"&&(a.closeRowMenu(),a.pin(r.thscode))},onClose:()=>a.closeRowMenu(),align:"end",portal:!0,listClassName:"capital-watchlist-rows",className:"capital-watchlist-actions"})))})),et=l("div",{className:g?"capital-watchlist-confirm capital-watchlist-confirm-open":"capital-watchlist-confirm","aria-hidden":g?void 0:"true"},l("div",{className:"capital-watchlist-confirmbox",role:g?"alertdialog":void 0,"aria-label":t("confirmTitle")},l("div",{className:"capital-watchlist-confirmtitle"},t("confirmTitle")),g?l("p",{className:"capital-watchlist-confirmdesc"},t("confirmDescPrefix"),l("strong",null,`${p.name} \xB7 ${p.ticker}`),t("confirmDescSuffix")):null,l("div",{className:"capital-watchlist-confirmactions"},l("button",{type:"button",className:"capital-watchlist-confirmbtn",onClick:()=>a.setPendingRemove(null)},t("confirmCancel")),l("button",{type:"button",className:"capital-watchlist-confirmbtn capital-watchlist-confirmdanger",onClick:()=>{let r=p;a.setPendingRemove(null),r!==null&&a.remove(r.thscode)}},t("confirmOk")))));return l(Pt,{open:!0,onClose:()=>a.close(),title:t("title"),headless:!0,shortcutModal:"watchlist",className:"capital-watchlist-dialog"},l("div",{className:"capital-watchlist-card",onKeyDown:Y},l("div",{className:"capital-watchlist-header"},l("h2",{className:"capital-watchlist-title"},t("title")),l("button",{type:"button",className:"capital-watchlist-close","aria-label":t("close"),onClick:()=>a.close()},l(O,{size:14}))),l("div",{className:"capital-watchlist-search",onBlur:G},l("div",{className:"capital-watchlist-field"},l("span",{className:"capital-watchlist-searchicon"},l(Et,{size:16})),l("input",{className:"capital-watchlist-input","data-modal-autofocus":!0,value:i.query,placeholder:t("searchPlaceholder"),onChange:r=>a.onQueryChange(r.target.value,r.isComposing),onCompositionStart:()=>a.beginComposition(),onCompositionEnd:r=>a.endComposition(r.target.value)}),i.query.length>0?l("button",{type:"button",className:"capital-watchlist-clear",title:t("clearInput"),"aria-label":t("clearInput"),onMouseDown:r=>r.preventDefault(),onClick:()=>a.onQueryChange("",!1)},l(O,{size:12})):null),V),i.addError!==null&&i.addError!==void 0?l("p",{className:"capital-watchlist-adderror",role:"status","data-code":i.addError.code},Kt(t,i.addError)):null,Z,at,l("div",{className:"capital-watchlist-footer"},l("div",{className:"capital-watchlist-footcol"},l("button",{type:"button",className:"capital-watchlist-refresh",disabled:i.refreshing||d,onClick:()=>{a.refresh()}},l(Ct,{size:14}),i.refreshing?t("refreshing"):t("refresh")),X),l("span",{className:"capital-watchlist-updated"},`${t("updated")} ${i.refreshed_at===null||i.refreshed_at===void 0?t("notRefreshed"):K(i.refreshed_at)}`)),et))}function Jt(e){e.effect(Qt,`${f}: styles`),e.effect(()=>e.locale.register(_,{zh:zt,en:Mt}),`${f}: dictionaries`);let a=new Map,t=n=>{let c=a.get(n);return c===void 0&&(c=new E,a.set(n,c)),c};e.effect(()=>()=>{for(let n of a.values())n.dispose();a.clear()},`${f}: per-session surfaces`);let s=n=>{let o=e.sessions?.list?.getSnapshot?.().byId?.[n]?.projectionValues?.agentPreset;return typeof o=="string"?o:void 0},i=new Set,d=n=>{let c=s(n);return c!==void 0?c===Rt:(i.has(n)||(i.add(n),Promise.resolve(e.sessions?.refreshProjections?.(n)).catch(()=>{})),!1)};e.slots.inject(L,()=>e.slots.register({name:L,id:"capital-watchlist-dialog",order:3,locale:_,inject:n=>{let c=t(n);return{hooks:{dialog:c.state},surface:c}}},Xt)),e.inject(["commandUi"],n=>{let c=e.locale.bind(_);n.effect(()=>n.commandUi.register({name:"watchlist",label:()=>c("command.label"),description:()=>c("command.description"),icon:vt,available:o=>d(o.sessionId),ui:{kind:"action",run:o=>{t(o.sessionId).open()}}}),`${f}: /watchlist contribution`)}),e.logger?.info?.(`${f}: \u5BA2\u6237\u7AEF\u534A\u8FB9\u5DF2\u6302\u8F7D\uFF08/watchlist \u83DC\u5355\u884C + \u81EA\u9009\u80A1\u5F39\u7A97\uFF09`)}exports.name=f;exports.inject=["slots","locale","commandUi","sessions"];exports.apply=Jt;
264
264
  return module.exports
265
265
  },
266
266
  })
@@ -150,9 +150,9 @@ const zh = {
150
150
  /** 行标签、开关的 aria-label,以及名称标红之外那句非颜色通道(红名与"红涨"同色)共用这一个词。 */
151
151
  holdingName: '持仓',
152
152
  predict: '预测',
153
- predictTip: 'AI预测该证券标的',
153
+ predictTip: 'AI预测',
154
154
  review: '复盘',
155
- reviewTip: 'AI复盘该证券标的',
155
+ reviewTip: 'AI复盘',
156
156
  /**
157
157
  * ⚠️「预测」与「复盘」写进输入框的那句话**只改这四行**(zh / en 各两处,两套语言必须同时改)。
158
158
  * 中间的 `名称 (thscode · 类型)` 是结构不是措辞,不住在这里:Agent 靠 thscode 认标的、
@@ -257,9 +257,9 @@ const en = {
257
257
  /** ⚠️ 这两条标签受**格宽预算**约束:动作列是定值 52px(见 CSS 里 grid 那一处),
258
258
  * 12px/500 下八个字符就顶到边。要改名先量长度,别让它溢出描边。 */
259
259
  predict: 'Predict',
260
- predictTip: 'AI prediction for this symbol',
260
+ predictTip: 'AI prediction',
261
261
  review: 'Review',
262
- reviewTip: 'AI review of this symbol',
262
+ reviewTip: 'AI review',
263
263
  predictPromptPrefix: 'Predict ',
264
264
  predictPromptSuffix: ' over the next 5 sessions: the likely path and key levels, the evidence behind the call, and how uncertain it is.',
265
265
  reviewPromptPrefix: 'Review ',
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v587d/capital-watchlist",
3
- "version": "2.7.7",
3
+ "version": "2.7.9",
4
4
  "description": "Capital 模式的用户自选股(宿主级清单 + Fuyao 报价快照 + /capital-watchlist 路由 + 输入框菜单弹窗):由 @v587d/capital-generation 随包携带并作为 host 平面行挂载。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v587d/capital-charts",
3
- "version": "2.7.7",
3
+ "version": "2.7.9",
4
4
  "description": "Capital 模式的图表前端组件(浏览器半边 + 序列旁路路由):由 @v587d/capital-generation 随包携带并作为 host 平面行挂载。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -7,6 +7,8 @@ import { agentSessionId, isRootAgent } from './root-tool-policy.js';
7
7
  import { SELECTED_SKILL_CATALOG as CATALOG, SELECTED_SKILL_SKILL_DIRS } from '../../selected-skills/catalog.js';
8
8
  export const SELECTED_SKILL_CATALOG = CATALOG;
9
9
  const PROVIDER_NAME = 'capital-selected-skills';
10
+ /** 本 preset 的身份:两条注册路径(`agent/created` 与 `agent-preset/selected`)共用一份。 */
11
+ const CAPITAL_PRESET_ID = 'capital-generation';
10
12
  // skills 根按 catalog 的「仓库 → 上游 SKILL.md 相对路径」现算:第三颗快照的上游把 skill 放在
11
13
  // plugins/us-stock-analysis/skills,不在 <repo>/skills 底下。写死目录列表的表现不是报错,
12
14
  // 而是"用户在卡片上勾了那一格、技能永远不出现"(AGENTS.md §9.7)。
@@ -37,7 +39,7 @@ function strictCapitalPreset(ctx, agent) {
37
39
  try {
38
40
  const presets = ctx.get?.('agentPresets');
39
41
  return typeof presets?.composedPreset === 'function'
40
- && presets.composedPreset(agent.ctx) === 'capital-generation';
42
+ && presets.composedPreset(agent.ctx) === CAPITAL_PRESET_ID;
41
43
  }
42
44
  catch {
43
45
  return false;
@@ -54,15 +56,22 @@ export function registerRootSelectedSkills(ctx, selection, createFilesystemProvi
54
56
  const listenCtx = ctx.root ?? ctx;
55
57
  if (typeof listenCtx.on !== 'function')
56
58
  return;
57
- const stop = listenCtx.on('agent/created', async ({ agent }) => {
58
- if (!agent || !isRootAgent(agent) || !strictCapitalPreset(ctx, agent))
59
+ // 一个 root Agent 只注册一次:下面两条事件路径会在同一个 Agent 上重叠(建会话时就带 Capital
60
+ // 预设 → `agent/created`;先按默认预设建、再 select 到 Capital → `agent-preset/selected`)。
61
+ const registered = new WeakSet();
62
+ const registerFor = async (agent) => {
63
+ if (!agent || registered.has(agent))
59
64
  return;
60
- const agentCtx = agent.ctx;
61
- if (!agentCtx || typeof agentCtx.inject !== 'function') {
62
- ctx.logger?.warn?.('capital-generation: selected skills are unavailable (root Agent cannot inject skills)');
65
+ if (!isRootAgent(agent) || !strictCapitalPreset(ctx, agent))
63
66
  return;
64
- }
67
+ registered.add(agent);
65
68
  try {
69
+ const agentCtx = agent.ctx;
70
+ if (!agentCtx || typeof agentCtx.inject !== 'function') {
71
+ registered.delete(agent);
72
+ ctx.logger?.warn?.('capital-generation: selected skills are unavailable (root Agent cannot inject skills)');
73
+ return;
74
+ }
66
75
  // agent/created 是串行事件、DSH 等监听器 settle 才继续创建:await 注入 Fiber,
67
76
  // provider 与 pre-step 钩子都在首轮 prompt 前落位(首轮 catalog 不与注册竞态)。
68
77
  await agentCtx.inject(['skills'], (injectedCtx) => {
@@ -138,12 +147,36 @@ export function registerRootSelectedSkills(ctx, selection, createFilesystemProvi
138
147
  });
139
148
  }
140
149
  catch (error) {
141
- // selected skills 是可选能力:注入失败只降级告警,不能把整个 Agent 创建挡掉。
150
+ // selected skills 是可选能力:注入失败只降级告警,不能把整个 Agent 创建挡掉;
151
+ // 同时撤掉登记,让后面的事件(下一次 select、别的注册路径)还有重试的余地。
152
+ registered.delete(agent);
142
153
  ctx.logger?.warn?.(`capital-generation: selected skills are unavailable (${String(error)})`);
143
154
  }
155
+ };
156
+ const stop = listenCtx.on('agent/created', ({ agent }) => registerFor(agent));
157
+ // 第二条路径:**先按默认预设建会话、再切到 Capital**(GUI 的真实顺序)。
158
+ // 2026-10-13 复核复现:会话(header `agentPreset: "cordis"`)建好后客户端才发
159
+ // `agentPresets.select('capital-generation')`,而 `agent/created` 在 select 之前就已经发完——
160
+ // 只挂那一条时本插件的 `apply()` 是在**这次 recompose 的 mount 里**才跑的,监听器出生就错过了
161
+ // 自己这个 Agent:设置卡 10 个开关全开、会话目录仍只有 preset 自带的 8 颗(真 boot graph 探针:
162
+ // create→select 8 颗 / 建会话时 mount 同一 preset 18 颗)。preset registry 在 mount 完成后才
163
+ // `session.append('agent-preset/selected')`,所以本行一定早于这条事件落位。
164
+ const onPresetEvent = listenCtx.on;
165
+ const stopPreset = onPresetEvent?.('agent-preset/selected', (sessionId, agentPreset) => {
166
+ if (agentPreset !== CAPITAL_PRESET_ID)
167
+ return;
168
+ const agents = ctx.get?.('agents');
169
+ const agent = agents?.get?.(String(sessionId));
170
+ if (agent === undefined)
171
+ return;
172
+ // emit 型事件不等待监听器;返回 promise 只为让单测能等到注册落地。registerFor 内部
173
+ // 自兜异常(失败只降级告警并撤登记,下一次事件还有重试的余地),这里不会产生未处理拒绝。
174
+ return registerFor(agent);
144
175
  });
145
176
  ctx.effect?.(() => () => {
146
177
  if (typeof stop === 'function')
147
178
  stop();
179
+ if (typeof stopPreset === 'function')
180
+ stopPreset();
148
181
  }, 'capital-generation: selected skill root listener');
149
182
  }
@@ -84,12 +84,26 @@ export class ChartSourceTokenStore {
84
84
  async issue(input) {
85
85
  const datasetId = readDatasetId(input.dataset_id);
86
86
  const taskId = readTaskId(input.task_id, true);
87
+ const now = this.now();
88
+ this.purgeExpired(now);
89
+ // 幂等:同一 session + task_id + dataset_id 在 TTL 内重复签发返回**同一个** token。
90
+ // 2026-10-10 真机(task_fh_300803_20261010):data_junior 改了视图方案后为同一 dataset
91
+ // 重签,跟着就是 7.9K 字符的思考回合——skill 里的"不要重签"警告拦不住,所以把幂等沉到
92
+ // 工具层。token 是读能力而非一次性凭证(resolve 不消费),复用没有语义损失。
93
+ for (const record of this.tokens.values()) {
94
+ if (record.dataset_id === datasetId && record.task_id === taskId && record.sourceSession.id === input.session.id) {
95
+ return {
96
+ chart_source_ref: record.chart_source_ref,
97
+ dataset_id: record.dataset_id,
98
+ task_id: record.task_id,
99
+ expires_at: record.expires_at,
100
+ };
101
+ }
102
+ }
87
103
  const inspection = await input.store.inspectDataset(datasetId, input.session, input.signal);
88
104
  if (!inspection.query_access.readable || !['array', 'envelope_item'].includes(inspection.query_access.shape)) {
89
105
  throw new ChartError('chart_source_invalid', `Dataset ${datasetId} cannot be used as a chart source (${inspection.query_access.reason ?? inspection.query_access.shape})`);
90
106
  }
91
- const now = this.now();
92
- this.purgeExpired(now);
93
107
  const token = this.newToken();
94
108
  if (!CHART_SOURCE_TOKEN_PATTERN.test(token)) {
95
109
  throw new ChartError('chart_source_invalid', 'generated chart_source_ref is invalid');
@@ -160,7 +174,8 @@ export function registerChartSourceTool(ctx, options) {
160
174
  const definition = {
161
175
  name: 'prepare_chart_source',
162
176
  description: '为当前 delegated data agent 的指定 Dataset 签发短期 chart_source_ref,供 visualization_specialist 通过受控 render_chart 读取。' +
163
- '只返回 opaque token 和小型元数据,不返回原始数据、文件路径或数据行;必须提供 dataset_id,可选 task_id。',
177
+ '只返回 opaque token 和小型元数据,不返回原始数据、文件路径或数据行;必须提供 dataset_id,可选 task_id。' +
178
+ '同一 task_id + dataset_id 重复调用幂等返回同一个 chart_source_ref(TTL 内),改了视图方案直接复用即可。',
164
179
  parameters: jsonObject({
165
180
  dataset_id: { type: 'string', description: '已授权的 DatasetRef dataset_id' },
166
181
  task_id: { type: 'string', description: '当前可视化任务标识;用于绑定 token,必填' },
@@ -337,9 +337,11 @@ const describeResultSchema = jsonObject({
337
337
  validation: profileValidationSchema,
338
338
  warnings: { type: 'array', items: { type: 'string' } },
339
339
  queries: { type: 'array', items: describeQueryOutcomeSchema },
340
- /** 仅 too_large:被拦下的形状、字节数与重试指引。 */
340
+ /** 仅 too_large:被拦下的形状、字节数、体积归因与重试指引。 */
341
341
  shape: { type: 'string', enum: ['array', 'envelope_item', 'document', 'none'] },
342
342
  bytes: { type: 'integer' },
343
+ facts_bytes: { type: 'integer' },
344
+ queries_bytes: { type: 'integer' },
343
345
  hint: { type: 'string' },
344
346
  }, ['status', 'dataset_id']);
345
347
  export function registerDatasetTools(ctx, store) {
@@ -383,7 +385,7 @@ export function registerDatasetTools(ctx, store) {
383
385
  withIsoTimeColumns(result, prepared.axis);
384
386
  return result;
385
387
  }),
386
- tool('describe_dataset', `读取一份 Dataset 的**默认入口**:一次调用完成 inspect(元数据与可读性/形状)、profile(宿主算基础质量与四类事实,写入 profile_ref)与受控 query(可选);原始 rows 不进入模型上下文。一次只处理一个 dataset_id——本轮有多份数据时,请在**同一条消息里一次发出多个调用**(本工具可并发执行,结果会一起返回),不要一份一份等。行集合返回:① 元数据 artifact_ref/capability/source_label/captured_at/retention_until 与 query_access.shape(array / envelope_item = 行集合;document = 顶层文档对象,只能 profile,queries 由宿主跳过);② profile 四类事实——statistics(count/sum/min/max/mean/分位数)、categories(distinct + 最多 5 个高频取值)、time_facts(覆盖范围与首行/末行取值;回答"最新值、区间涨跌"必须用它,不要用 min/max 代替)、structure(嵌套路径摘要);③ queries——每条的 QueryResult,或该条自己的 error(单条失败不影响其余)。columns_of_interest 只对这些列返回 statistics/categories/schema(并同样收窄 time_facts 的首末值投影,时间列永远保留),是收窄结果体积的唯一手段。结果超过 ${SAFE_RESULT_CHARS} 码点时宿主不返回超长载荷,而返回 {status:'too_large', profile_ref, columns, hint}:按 hint 用 columns_of_interest(或减少 queries,最多 ${MAX_DESCRIBE_QUERIES} 条)重发一次即可。单点复核仍可用 inspect_dataset / profile_dataset / query_dataset;不接受任何文件路径、脚本内容或自定义表达式。`, describeParametersSchema, describeResultSchema, async (args, exec) => describeDataset({
388
+ tool('describe_dataset', `读取一份 Dataset 的**默认入口**:一次调用完成 inspect(元数据与可读性/形状)、profile(宿主算基础质量与四类事实,写入 profile_ref)与受控 query(可选);原始 rows 不进入模型上下文。一次只处理一个 dataset_id——本轮有多份数据时,请在**同一条消息里一次发出多个调用**(本工具可并发执行,结果会一起返回),不要一份一份等。行集合返回:① 元数据 artifact_ref/capability/source_label/captured_at/retention_until 与 query_access.shape(array / envelope_item = 行集合;document = 顶层文档对象,只能 profile,queries 由宿主跳过);② profile 四类事实——statistics(count/sum/min/max/mean/分位数)、categories(distinct + 最多 5 个高频取值)、time_facts(覆盖范围与首行/末行取值;回答"最新值、区间涨跌"必须用它,不要用 min/max 代替)、structure(嵌套路径摘要);③ queries——每条的 QueryResult,或该条自己的 error(单条失败不影响其余)。columns_of_interest 只对这些列返回 statistics/categories/schema(并同样收窄 time_facts 的首末值投影,时间列永远保留),是收窄结果体积的唯一手段。结果超过 ${SAFE_RESULT_CHARS} 码点时宿主不返回超长载荷,而返回 {status:'too_large', profile_ref, columns, bytes, facts_bytes, queries_bytes, hint}:facts_bytes/queries_bytes 是体积归因(哪边大砍哪边),按 hint 重发一次即可——queries 大就先去掉 queries(聚合改单独走 query_dataset),facts 大就用 columns_of_interest 收窄列(或减少 queries,最多 ${MAX_DESCRIBE_QUERIES} 条)。单点复核仍可用 inspect_dataset / profile_dataset / query_dataset;不接受任何文件路径、脚本内容或自定义表达式。`, describeParametersSchema, describeResultSchema, async (args, exec) => describeDataset({
387
389
  store,
388
390
  session: delegatedSession(exec, 'describe_dataset'),
389
391
  request: normalizeDescribeArgs(args),
@@ -77,6 +77,10 @@ export interface DescribeTooLarge {
77
77
  shape: DatasetInspection['query_access']['shape'];
78
78
  columns: string[];
79
79
  bytes: number;
80
+ /** 体积归因:facts(元数据 + profile 事实块)部分的码点数。 */
81
+ facts_bytes: number;
82
+ /** 体积归因:queries(含各条 result)部分的码点数。 */
83
+ queries_bytes: number;
80
84
  hint: string;
81
85
  }
82
86
  export type DescribeOutput = DescribeResult | DescribeTooLarge;
@@ -240,6 +240,12 @@ export async function describeDataset(input) {
240
240
  const encoded = JSON.stringify(value);
241
241
  const bytes = codePointLength(encoded);
242
242
  if (bytes > SAFE_RESULT_CHARS) {
243
+ // 体积归因:把 queries 部分单量出来,hint 指名先砍哪边。2026-10-10 真机(task_fh_300803_20261010):
244
+ // 两份宽表各带 5-6 聚合的 queries 打穿闸门,而回执只说"用 columns_of_interest 收窄"——列本来
245
+ // 已经很窄,超预算的其实是 queries,模型只好 describe(去 queries)+ query_dataset 各来一轮,
246
+ // 4 次调用里 2 次本可省。归因字段让 hint 直指大头,不引入第二道闸门(⛔ 体积闸门仍只有一道)。
247
+ const queriesBytes = codePointLength(JSON.stringify(value.queries));
248
+ const factsBytes = bytes - queriesBytes;
243
249
  return compact({
244
250
  status: 'too_large',
245
251
  dataset_id: inspection.dataset_id,
@@ -247,9 +253,13 @@ export async function describeDataset(input) {
247
253
  shape,
248
254
  columns: profile.columns,
249
255
  bytes,
256
+ facts_bytes: factsBytes,
257
+ queries_bytes: queriesBytes,
250
258
  hint: shape === 'document'
251
259
  ? '文档型 Dataset 的结果超预算:直接调 profile_dataset 取有界内容(本工具的列过滤对文档无效)'
252
- : '结果超预算:重发一次 describe_dataset,用 columns_of_interest 指定本次问题真正需要的列,或减少 queries 条数',
260
+ : queriesBytes > factsBytes
261
+ ? `结果超预算(queries 占 ${queriesBytes} > facts 占 ${factsBytes}):先去掉 queries(只 describe 不带 queries,聚合改单独走 query_dataset),facts 仍超再用 columns_of_interest 收窄列`
262
+ : `结果超预算(facts 占 ${factsBytes} ≥ queries 占 ${queriesBytes}):先用 columns_of_interest 指定本次问题真正需要的列,或减少 queries 条数`,
253
263
  });
254
264
  }
255
265
  return value;
package/lib/index.d.ts CHANGED
@@ -261,6 +261,23 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
261
261
  }>>, "defined">;
262
262
  }>>, "defined">;
263
263
  }>>, "plain">;
264
+ export type CapitalSettingsSource = 'settings-describe' | 'config-editor' | 'preset';
265
+ /**
266
+ * 读取 `capital-config` 条目的生效配置。三级取数、逐级兜底:
267
+ * 1. `settings.describe()`:活动条目的已应用视图(0.1.7 官方读回面);
268
+ * 2. `configEditor.entries()` 的条目保存层:设置卡写入的就是这层(complete raw config)。
269
+ * describe() 在条目 fiber 未挂好的窗口会**整个跳过条目**,用户已保存的值仍然在这里可读;
270
+ * 3. preset 配置兜底,且必须可辨认(`source === 'preset'`)——"读不到"不许伪装成"用户全关"。
271
+ *
272
+ * ⛔ 服务引用一律**调用期现取**(AGENTS.md §9.7):装配期 `ctx.get()` 押的是"宿主服务已注册"
273
+ * 这个外部时刻——boot 里各 fiber 并行 apply,settings / configEditor 晚于本插件注册时,装配期
274
+ * 捕获到 undefined,整场进程会静默降级成 preset 默认。2026-10-13 复盘(session-bb8635a1:
275
+ * 07:51 保存 10 个开关、07:54 建会话读到全关、08:30 重组后同一条读取路径立刻读对)就是这一族。
276
+ */
277
+ export declare function readCapitalSettings(ctx: Context, bootConfig: Config): {
278
+ config: Config;
279
+ source: CapitalSettingsSource;
280
+ };
264
281
  /**
265
282
  * 把可选的用户人设文本转成独立 system-prompt section(官方 systemPrompt
266
283
  * registry 的注册对象)。空白输入返回 undefined(不注册);超长抛错;
package/lib/index.js CHANGED
@@ -150,6 +150,41 @@ export const Config = z.object({
150
150
  retriever: RetrieverSchema.default({ baseURL: '', credentialRef: 'ANYSEARCH_API_KEY', windDocs: { endpoint: '', credentialRef: 'WIND_API_KEY', timeoutMs: 60000 }, localFetch: { ...LOCAL_FETCH_DEFAULTS }, paddleOcr: { ...PADDLE_OCR_DEFAULTS } })
151
151
  .description('web_retriever 配置(可选;缺省使用 AnySearch 默认地址与凭据名)'),
152
152
  });
153
+ /**
154
+ * 读取 `capital-config` 条目的生效配置。三级取数、逐级兜底:
155
+ * 1. `settings.describe()`:活动条目的已应用视图(0.1.7 官方读回面);
156
+ * 2. `configEditor.entries()` 的条目保存层:设置卡写入的就是这层(complete raw config)。
157
+ * describe() 在条目 fiber 未挂好的窗口会**整个跳过条目**,用户已保存的值仍然在这里可读;
158
+ * 3. preset 配置兜底,且必须可辨认(`source === 'preset'`)——"读不到"不许伪装成"用户全关"。
159
+ *
160
+ * ⛔ 服务引用一律**调用期现取**(AGENTS.md §9.7):装配期 `ctx.get()` 押的是"宿主服务已注册"
161
+ * 这个外部时刻——boot 里各 fiber 并行 apply,settings / configEditor 晚于本插件注册时,装配期
162
+ * 捕获到 undefined,整场进程会静默降级成 preset 默认。2026-10-13 复盘(session-bb8635a1:
163
+ * 07:51 保存 10 个开关、07:54 建会话读到全关、08:30 重组后同一条读取路径立刻读对)就是这一族。
164
+ */
165
+ export function readCapitalSettings(ctx, bootConfig) {
166
+ const settings = ctx.get('settings');
167
+ try {
168
+ const resolved = settings?.describe?.().find((entry) => entry.ns === CAPITAL_CONFIG_ENTRY_ID)?.value;
169
+ // 这里再用本插件的 Config 过一遍:既补默认值,也把 schema 漂移变成可查的错误,
170
+ // 而不是把 capital-config schema 里的未知/缺失字段静默带进运行期配置。
171
+ if (resolved && typeof resolved === 'object')
172
+ return { config: Config(resolved), source: 'settings-describe' };
173
+ }
174
+ catch {
175
+ // 条目未装配 / schema 漂移:落到保存层再试,不静默吞掉。
176
+ }
177
+ const configEditor = ctx.get('configEditor');
178
+ try {
179
+ const raw = configEditor?.entries?.().find((row) => row?.options?.id === CAPITAL_CONFIG_ENTRY_ID)?.options?.config;
180
+ if (raw && typeof raw === 'object')
181
+ return { config: Config(raw), source: 'config-editor' };
182
+ }
183
+ catch {
184
+ // 保存层也不可读:只剩 preset 兜底。
185
+ }
186
+ return { config: bootConfig, source: 'preset' };
187
+ }
153
188
  /**
154
189
  * 把可选的用户人设文本转成独立 system-prompt section(官方 systemPrompt
155
190
  * registry 的注册对象)。空白输入返回 undefined(不注册);超长抛错;
@@ -189,29 +224,26 @@ export function apply(ctx, config) {
189
224
  // 消失),而是 **profile 条目的表单投影**:可编辑字段由条目自己的 Config schema 里的
190
225
  // `.volatile()` 声明,`describe()` 按条目 id 返回解析后的值。所以我们按随包的
191
226
  // `capital-config` **条目 id** 找那一行,而不是按自造的命名空间。
192
- const settings = ctx.get('settings');
227
+ let lastSettingsSource;
193
228
  const readEffectiveConfig = () => {
194
- let resolvedConfig = config;
195
- try {
196
- const resolved = settings?.describe?.().find((entry) => entry.ns === CAPITAL_CONFIG_ENTRY_ID)?.value;
197
- // 这里再用本插件的 Config 过一遍:既补默认值,也把 schema 漂移变成可查的错误,
198
- // 而不是把 capital-config schema 里的未知/缺失字段静默带进运行期配置。
199
- if (resolved && typeof resolved === 'object')
200
- resolvedConfig = Config(resolved);
201
- }
202
- catch {
203
- // 条目未注册或解析失败时沿用 preset 配置。
229
+ const { config: resolved, source } = readCapitalSettings(ctx, config);
230
+ if (source !== lastSettingsSource) {
231
+ // 状态翻转才告警(读取是每轮现读的,不能逐次刷屏)。"读不到"被伪装成"用户全关"
232
+ // 是 2026-10-13 精选 Skills 消失 36 分钟无人能定位的直接原因——回落必须留声。
233
+ if (source === 'preset' && (ctx.get('settings') !== undefined || ctx.get('configEditor') !== undefined)) {
234
+ ctx.logger?.warn?.('capital-generation: capital-config 设置暂不可读,回落 preset 配置(精选 Skills 按默认全关;恢复后下一轮自动刷新)');
235
+ }
236
+ lastSettingsSource = source;
204
237
  }
205
- return resolvedConfig;
238
+ return resolved;
206
239
  };
207
240
  const effectiveConfig = readEffectiveConfig();
208
241
  // selectedSkills 是 live 的 settings 偏好:provider 在每轮 agent/pre-step 与每次
209
- // list()/get() 调用现读,切换开关不需要新建会话(见 docs/dev/selected-skills.md);
210
- // 无 settings 服务时沿用 preset 配置,避免为静态关闭配置额外挂一个永远空转的监听器。
211
- const selectedSkills = typeof settings?.describe === 'function'
212
- ? () => readEffectiveConfig().selectedSkills ?? {}
213
- : effectiveConfig.selectedSkills ?? {};
214
- registerRootSelectedSkills(ctx, selectedSkills);
242
+ // list()/get() 调用现读,切换开关不需要新建会话(见 docs/dev/selected-skills.md)。
243
+ // 一律传 reader 函数、不按"有没有 settings 服务"降级成静态值:那条降级分支正是
244
+ // 2026-10-13 事故的静默死路(装配期捕获不到服务 → 静态全关 → provider 连监听都不挂,
245
+ // 整场进程没救)。
246
+ registerRootSelectedSkills(ctx, () => readEffectiveConfig().selectedSkills ?? {});
215
247
  // ── data_collector 域:宿主侧 Dataset 落盘 + 取数执行器 ─────────────────────
216
248
  // 落盘通过 DSH 官方 fs/sandbox 服务完成,根目录恒为调用方 session 的
217
249
  // workspace cwd(exec.agent.session.header.cwd),服从当前 permission。
@@ -6,7 +6,7 @@
6
6
  * between validation and connect. Closing that window would require a custom
7
7
  * dispatcher; this module keeps the same explicit trade-off as dsh-search-first.
8
8
  */
9
- export declare const LOCAL_FETCH_CLIENT_VERSION = "2.7.7";
9
+ export declare const LOCAL_FETCH_CLIENT_VERSION = "2.7.9";
10
10
  export declare const LOCAL_FETCH_MAX_URL_LENGTH = 2048;
11
11
  export type LocalFetchErrorCode = 'ABORTED' | 'TIMEOUT' | 'INVALID_URL' | 'BLOCKED_URL' | 'DNS' | 'REDIRECT' | 'HTTP' | 'TOO_LARGE' | 'UNSUPPORTED_CONTENT_TYPE';
12
12
  export declare class LocalFetchError extends Error {
@@ -7,7 +7,7 @@
7
7
  * dispatcher; this module keeps the same explicit trade-off as dsh-search-first.
8
8
  */
9
9
  import { htmlToMarkdown, stripInvisibleText } from './html-markdown.js';
10
- export const LOCAL_FETCH_CLIENT_VERSION = '2.7.7';
10
+ export const LOCAL_FETCH_CLIENT_VERSION = '2.7.9';
11
11
  export const LOCAL_FETCH_MAX_URL_LENGTH = 2048;
12
12
  export class LocalFetchError extends Error {
13
13
  code;
@@ -52,7 +52,7 @@ export interface WindCallResult {
52
52
  * `test/chart-composition.test.mjs` 守着(会因漂移而失败),这里原本是写死的第二处,
53
53
  * 一次发版就得记得改两遍。所以本常量由测试一并核对(见 `test/wind-client.test.mjs`)。
54
54
  */
55
- export declare const WIND_CLIENT_VERSION = "2.7.7";
55
+ export declare const WIND_CLIENT_VERSION = "2.7.9";
56
56
  export interface WindClient {
57
57
  callTool(toolName: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<WindCallResult>;
58
58
  }
@@ -35,7 +35,7 @@ export const WIND_SERVER_ENDPOINTS = {
35
35
  * `test/chart-composition.test.mjs` 守着(会因漂移而失败),这里原本是写死的第二处,
36
36
  * 一次发版就得记得改两遍。所以本常量由测试一并核对(见 `test/wind-client.test.mjs`)。
37
37
  */
38
- export const WIND_CLIENT_VERSION = '2.7.7';
38
+ export const WIND_CLIENT_VERSION = '2.7.9';
39
39
  function errorText(error) {
40
40
  return error instanceof Error ? error.message : String(error);
41
41
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v587d/capital-generation",
3
- "version": "2.7.7",
3
+ "version": "2.7.9",
4
4
  "description": "Capital Generation:面向中国散户的 AI 投资助手插件(Capital mode Agent Preset)",
5
5
  "icon": "assets/cg-icon.png",
6
6
  "author": "v587d",
@@ -40,6 +40,8 @@
40
40
  "selected-skills/peter-lynch-skill",
41
41
  "selected-skills/trading-skills",
42
42
  "selected-skills/claude-for-financial-services-cn",
43
+ "selected-skills/financeskills",
44
+ "selected-skills/quant-agent-skills",
43
45
  "cordis.patch.yml",
44
46
  "assets/cg-icon.png",
45
47
  "README.md",