@v587d/capital-generation 2.7.0 → 2.7.1

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 (80) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/LICENSE +1 -1
  3. package/README.md +7 -7
  4. package/THIRD_PARTY_NOTICES.md +12 -4
  5. package/capital-config/client.js +50 -10
  6. package/capital-config/client.src.cjs +376 -62
  7. package/capital-config/index.js +168 -5
  8. package/capital-config/package.json +1 -1
  9. package/capital-watchlist/package.json +1 -1
  10. package/chart-ui/package.json +1 -1
  11. package/lib/agents/selected-skills-provider.js +5 -5
  12. package/lib/index.d.ts +4 -28
  13. package/lib/index.js +8 -18
  14. package/lib/web-retriever/local-fetch.d.ts +1 -1
  15. package/lib/web-retriever/local-fetch.js +1 -1
  16. package/lib/web-retriever/wind-client.d.ts +1 -1
  17. package/lib/web-retriever/wind-client.js +1 -1
  18. package/package.json +2 -1
  19. package/selected-skills/InvestSkill/ADDING-NEW-SKILLS.md +546 -0
  20. package/selected-skills/InvestSkill/CHANGELOG.md +373 -0
  21. package/selected-skills/InvestSkill/CI-CD-GUIDE.md +432 -0
  22. package/selected-skills/InvestSkill/CLAUDE.md +148 -0
  23. package/selected-skills/InvestSkill/CONTRIBUTING.md +291 -0
  24. package/selected-skills/InvestSkill/DEPLOYMENTS.md +321 -0
  25. package/selected-skills/InvestSkill/FAQ.md +509 -0
  26. package/selected-skills/InvestSkill/GEMINI.md +419 -0
  27. package/selected-skills/InvestSkill/LICENSE +21 -0
  28. package/selected-skills/InvestSkill/PLATFORM-COMPATIBILITY.md +529 -0
  29. package/selected-skills/InvestSkill/README-claude-code.md +435 -0
  30. package/selected-skills/InvestSkill/README-cursor.md +475 -0
  31. package/selected-skills/InvestSkill/README-gemini.md +532 -0
  32. package/selected-skills/InvestSkill/README-ollama.md +106 -0
  33. package/selected-skills/InvestSkill/README-zh-TW.md +461 -0
  34. package/selected-skills/InvestSkill/README.md +311 -0
  35. package/selected-skills/InvestSkill/RELEASE-QUICK-REFERENCE.md +230 -0
  36. package/selected-skills/InvestSkill/RELEASE_NOTES.md +121 -0
  37. package/selected-skills/InvestSkill/SECURITY.md +232 -0
  38. package/selected-skills/InvestSkill/TODO.md +28 -0
  39. package/selected-skills/InvestSkill/UPSTREAM.md +62 -0
  40. package/selected-skills/InvestSkill/install.sh +212 -0
  41. package/selected-skills/InvestSkill/package.json +64 -0
  42. package/selected-skills/InvestSkill/plugins/us-stock-analysis/README.md +119 -0
  43. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/10k-digest/SKILL.md +338 -0
  44. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/bear-case/SKILL.md +233 -0
  45. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/catalyst-calendar/SKILL.md +327 -0
  46. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/chart-master/SKILL.md +648 -0
  47. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/competitor-analysis/SKILL.md +478 -0
  48. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/dcf-valuation/SKILL.md +109 -0
  49. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/dividend-analysis/SKILL.md +684 -0
  50. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/earnings-call-analysis/SKILL.md +456 -0
  51. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/earnings-preview/SKILL.md +277 -0
  52. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/economics-analysis/SKILL.md +349 -0
  53. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/etf-analysis/SKILL.md +279 -0
  54. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/fact-check/SKILL.md +288 -0
  55. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/financial-report-analyst/SKILL.md +544 -0
  56. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/full-report/SKILL.md +301 -0
  57. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/fundamental-analysis/SKILL.md +67 -0
  58. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/industry-map/SKILL.md +336 -0
  59. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/insider-trading/SKILL.md +502 -0
  60. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/institutional-ownership/SKILL.md +548 -0
  61. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/learning-coach/SKILL.md +311 -0
  62. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/options-analysis/SKILL.md +495 -0
  63. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/portfolio-review/SKILL.md +465 -0
  64. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/position-ladder/SKILL.md +429 -0
  65. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/report-generator/SKILL.md +857 -0
  66. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/research-bundle/SKILL.md +94 -0
  67. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/result-validator/SKILL.md +174 -0
  68. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/risk-stress-test/SKILL.md +293 -0
  69. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/sector-analysis/SKILL.md +426 -0
  70. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/short-interest/SKILL.md +397 -0
  71. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/stock-eval/SKILL.md +645 -0
  72. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/stock-screener/SKILL.md +244 -0
  73. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/stock-valuation/SKILL.md +640 -0
  74. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/tax-lens/SKILL.md +351 -0
  75. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/technical-analysis/SKILL.md +654 -0
  76. package/selected-skills/InvestSkill/plugins/us-stock-analysis/skills/thesis-tracker/SKILL.md +317 -0
  77. package/selected-skills/README.md +15 -5
  78. package/selected-skills/catalog.js +566 -14
  79. package/selected-skills/investment-skills/UPSTREAM.md +1 -1
  80. package/selected-skills/investment-skills/skills/buffett-investment-framework/SKILL.md +1 -1
@@ -1,5 +1,5 @@
1
1
  import z from '@deepseek-ai/schemastery'
2
- import { SELECTED_SKILL_CATALOG } from '../selected-skills/catalog.js'
2
+ import { SELECTED_SKILL_CATALOG, SELECTED_SKILL_SKILL_DIRS } from '../selected-skills/catalog.js'
3
3
 
4
4
  export const name = 'capital-config'
5
5
 
@@ -114,10 +114,173 @@ export const Config = z.object({
114
114
  })
115
115
 
116
116
  /**
117
- * 本行**不消费**自己的配置,也不需要注册任何服务:可编辑性全部是 schema 事实
118
- * (`.volatile()`),`dsh-settings` 从条目 Config 投影出表单,主插件再经
119
- * `settings.describe()` 读回解析值。所以这里只留一行日志,证明这颗行激活了。
117
+ * 「精选 Skills」那一格的**原文旁路**:卡片上的「详情」悬浮要显示 `SKILL.md` 原文,
118
+ * 而原文是随包携带的快照文件(35 份共 ~750 KB)。
119
+ *
120
+ * 为什么走一条本机路由,而不是把原文打进客户端 bundle:客户端 bundle 在页面加载那一刻
121
+ * 整体送达浏览器(`window.__ModuleLoader__.load` 是单文件 IIFE,没有按需分片),750 KB 会
122
+ * 让每一次打开插件页都付一遍——包括从不点「详情」的那次。旁路只在悬停时取一份,且取的是
123
+ * **磁盘上当前那份**,不是构建期抄的副本:抄来的原文会随快照更新而变旧,而这块 UI 说的
124
+ * 是"这就是原文"(控件对自己的状态说谎 = 事故)。
125
+ *
126
+ * 闭集:路径按 `SELECTED_SKILL_CATALOG` × `SELECTED_SKILL_SKILL_DIRS` 在模块加载时现算成
127
+ * `Map<skill 名, file: URL>`,请求里的名字**只做这张表的键**,不参与任何路径拼接——
128
+ * `%2F..%2F` 之类一律落在"表里没有这个名字"那一侧(404)。路径用 `URL` 表示:`fs` 直接收
129
+ * `file:` URL,省掉一次 `fileURLToPath`(也就省掉在 import 期依赖 node 内置模块)。
130
+ *
131
+ * ⛔ 认证围栏与 `/capital-charts`、`/capital-watchlist` 同一写法(`connection.requestRejection`,
132
+ * docs/dev/chart-presentation.md §6.1):`webServer.register({ kind: 'prefix' })` 本身不做任何认证。
133
+ */
134
+ export const SKILL_DOC_ROUTE = '/capital-skills'
135
+ /** 单份原文的字节上限:超限**整份拒绝、绝不截断**("原文"被切一半比没有原文更误导人)。 */
136
+ export const MAX_SKILL_DOC_BYTES = 128 * 1024
137
+
138
+ const SKILL_DOC_SUFFIX = 'SKILL.md'
139
+
140
+ /** catalog 里的顺序 = 卡片上的顺序,所以这里只多算一份"名字 → 快照文件"的索引。 */
141
+ export const SKILL_DOCS = new Map(SELECTED_SKILL_CATALOG.map((entry) => [
142
+ entry.name,
143
+ new URL(`../selected-skills/${entry.repository}/${SELECTED_SKILL_SKILL_DIRS[entry.repository]}/${entry.name}/${SKILL_DOC_SUFFIX}`, import.meta.url),
144
+ ]))
145
+
146
+ function fsModule() {
147
+ const processLike = globalThis.process
148
+ const fs = processLike?.getBuiltinModule?.('node:fs')
149
+ if (!fs || typeof fs.readFileSync !== 'function') throw new Error('capital-config: Node fs is unavailable')
150
+ return fs
151
+ }
152
+
153
+ function sendJson(res, status, payload) {
154
+ res.statusCode = status
155
+ res.setHeader('content-type', 'application/json; charset=utf-8')
156
+ res.setHeader('cache-control', 'no-store')
157
+ res.setHeader('x-content-type-options', 'nosniff')
158
+ res.end(JSON.stringify(payload))
159
+ }
160
+
161
+ /**
162
+ * @param options.readFile - `(url) => string | Buffer`,用例注入假读盘。
163
+ * @param options.authorize - `(req) => 401 | 403 | undefined`;非空即拒,**且一次都不碰文件系统**。
164
+ */
165
+ export function createSkillDocHandler(options = {}) {
166
+ const readFile = options.readFile ?? ((target) => fsModule().readFileSync(target, 'utf8'))
167
+ const statSize = options.statSize ?? ((target) => fsModule().statSync(target).size)
168
+ const authorize = options.authorize
169
+ return async function handler(req, res) {
170
+ if (typeof authorize === 'function') {
171
+ let rejection
172
+ try {
173
+ rejection = authorize(req)
174
+ } catch {
175
+ // 围栏自己答不上来时必须 fail closed:放行就等于"认证失败 = 不认证"。
176
+ rejection = 401
177
+ }
178
+ if (rejection !== undefined && rejection !== null) {
179
+ res.statusCode = rejection
180
+ res.setHeader('content-type', 'text/plain; charset=utf-8')
181
+ res.setHeader('cache-control', 'no-store')
182
+ res.end(rejection === 401 ? 'unauthorized' : 'forbidden')
183
+ return
184
+ }
185
+ }
186
+ if (req?.method !== 'GET') {
187
+ sendJson(res, 405, { error: 'method_not_allowed' })
188
+ return
189
+ }
190
+ let pathname
191
+ try {
192
+ pathname = new URL(req.url ?? '/', 'http://localhost').pathname
193
+ } catch {
194
+ sendJson(res, 400, { error: 'bad_request' })
195
+ return
196
+ }
197
+ if (!pathname.startsWith(`${SKILL_DOC_ROUTE}/`)) {
198
+ sendJson(res, 404, { error: 'not_found' })
199
+ return
200
+ }
201
+ const match = /^([^/]+)\.md$/.exec(pathname.slice(`${SKILL_DOC_ROUTE}/`.length))
202
+ if (!match) {
203
+ sendJson(res, 404, { error: 'not_found' })
204
+ return
205
+ }
206
+ let name
207
+ try {
208
+ name = decodeURIComponent(match[1])
209
+ } catch {
210
+ sendJson(res, 400, { error: 'bad_request' })
211
+ return
212
+ }
213
+ const target = SKILL_DOCS.get(name)
214
+ if (target === undefined) {
215
+ sendJson(res, 404, { error: 'skill_not_catalogued', name })
216
+ return
217
+ }
218
+ let bytes
219
+ try {
220
+ bytes = statSize(target)
221
+ } catch {
222
+ // 快照没随包落地(装到一半 / files 清单漏了):说清楚"读不到",别回一份空原文当好结果。
223
+ sendJson(res, 404, { error: 'skill_doc_unreadable', name })
224
+ return
225
+ }
226
+ if (bytes > MAX_SKILL_DOC_BYTES) {
227
+ sendJson(res, 413, { error: 'skill_doc_too_large', name, limit: MAX_SKILL_DOC_BYTES })
228
+ return
229
+ }
230
+ let body
231
+ try {
232
+ body = readFile(target)
233
+ } catch {
234
+ sendJson(res, 404, { error: 'skill_doc_unreadable', name })
235
+ return
236
+ }
237
+ res.statusCode = 200
238
+ res.setHeader('content-type', 'text/plain; charset=utf-8')
239
+ res.setHeader('cache-control', 'no-store')
240
+ res.setHeader('x-content-type-options', 'nosniff')
241
+ res.end(typeof body === 'string' ? body : Buffer.from(body))
242
+ }
243
+ }
244
+
245
+ /**
246
+ * 卡片那侧拼 URL 的唯一口径(文件名里带 `.` 的 slug 也要能拼,所以走 encodeURIComponent)。
247
+ * 客户端 bundle 与这里是**同一条字符串**的两端:漂移的表现为"详情永远读不到",由
248
+ * `test/capital-config.test.mjs` 的同字断言钉住(客户端不能 import 本模块 ⇒ 只能对着产物量)。
249
+ */
250
+ export function skillDocUrl(name) {
251
+ return `${SKILL_DOC_ROUTE}/${encodeURIComponent(name)}.md`
252
+ }
253
+
254
+ /**
255
+ * 本行消费两件事:自己的配置(schema 事实,见上)与快照原文的读盘旁路。
256
+ *
257
+ * `webServer` 只走 `inject`——`ctx.get('webServer')` 解析得到值**不代表**属性访问合法
258
+ * (cordis 的属性代理只认"本层声明过 inject"),探测式写法会把正确性押在装配顺序上,
259
+ * 这条踩过两次(见 `chart-ui/index.js` 的同一段注释)。认证面 `connection` 反之要**惰性**
260
+ * 解析:它缺席(Electron / file:// 这类没有浏览器认证面的载体)就退化成"没有认证面"的旧行为,
261
+ * 但解析抛错一律 401。
120
262
  */
121
263
  export function apply(ctx) {
122
- ctx.logger?.info?.('capital-config: settings entry active (volatile config surface)')
264
+ const authorize = (req) => {
265
+ let connection
266
+ try {
267
+ connection = ctx.get('connection')
268
+ } catch {
269
+ return 401
270
+ }
271
+ if (connection === undefined || connection === null) return undefined
272
+ if (typeof connection.requestRejection !== 'function') return undefined
273
+ return connection.requestRejection(req)
274
+ }
275
+ ctx.inject(['webServer'], (webCtx) => {
276
+ webCtx.effect(
277
+ () => webCtx.webServer.register({
278
+ kind: 'prefix',
279
+ path: SKILL_DOC_ROUTE,
280
+ handler: createSkillDocHandler({ authorize }),
281
+ }),
282
+ 'capital-config: skill 原文旁路',
283
+ )
284
+ })
285
+ ctx.logger?.info?.('capital-config: settings entry active (volatile config surface + skill 原文旁路)')
123
286
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v587d/capital-config",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
4
4
  "description": "Capital 模式的取数凭据与偏好配置行:卡片坐在 @v587d/capital-generation 插件主页的「配置」段,点这一行本身没有表单。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@v587d/capital-watchlist",
3
- "version": "2.7.0",
3
+ "version": "2.7.1",
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.0",
3
+ "version": "2.7.1",
4
4
  "description": "Capital 模式的图表前端组件(浏览器半边 + 序列旁路路由):由 @v587d/capital-generation 随包携带并作为 host 平面行挂载。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -4,13 +4,13 @@ import { agentSessionId, isRootAgent } from './root-tool-policy.js';
4
4
  // The catalog is a shipped data file outside the TypeScript root; runtime keeps this
5
5
  // import so the published lib resolves the same metadata beside the pinned snapshots.
6
6
  // @ts-expect-error catalog.js is intentionally maintained as package data.
7
- import { SELECTED_SKILL_CATALOG as CATALOG } from '../../selected-skills/catalog.js';
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
- const SKILL_ROOTS = [
11
- fileURLToPath(new URL('../../selected-skills/investment-skills/skills', import.meta.url)),
12
- fileURLToPath(new URL('../../selected-skills/china-stock-research-skills/skills', import.meta.url)),
13
- ];
10
+ // skills 根按 catalog 的「仓库 → 上游 SKILL.md 相对路径」现算:第三颗快照的上游把 skill 放在
11
+ // plugins/us-stock-analysis/skills,不在 <repo>/skills 底下。写死目录列表的表现不是报错,
12
+ // 而是"用户在卡片上勾了那一格、技能永远不出现"(AGENTS.md §9.7)。
13
+ const SKILL_ROOTS = Object.entries(SELECTED_SKILL_SKILL_DIRS).map(([repository, skillsDir]) => fileURLToPath(new URL(`../../selected-skills/${repository}/${skillsDir}`, import.meta.url)));
14
14
  function createFilesystemSkillProvider(ctx, control, config) {
15
15
  return new FileSystemSkillProvider(ctx, control, config);
16
16
  }
package/lib/index.d.ts CHANGED
@@ -93,21 +93,9 @@ export interface Config {
93
93
  export declare const Config: z<Schemastery.ObjectS<NoInfer<{
94
94
  customPersona: z<string, string, "defined">;
95
95
  selectedSkills: z<Schemastery.ObjectS<NoInfer<{
96
- buffettFramework: z<boolean, boolean, "defined">;
97
- financialHealth: z<boolean, boolean, "defined">;
98
- riskWarningCatalysts: z<boolean, boolean, "defined">;
99
- valuationInvestmentStrategy: z<boolean, boolean, "defined">;
100
- strategyBusinessTransition: z<boolean, boolean, "defined">;
101
- industryCompetitionMoat: z<boolean, boolean, "defined">;
102
- businessDecompositionOrderQuality: z<boolean, boolean, "defined">;
96
+ [k: string]: z<boolean, boolean, "defined">;
103
97
  }>>, Schemastery.ObjectT<NoInfer<{
104
- buffettFramework: z<boolean, boolean, "defined">;
105
- financialHealth: z<boolean, boolean, "defined">;
106
- riskWarningCatalysts: z<boolean, boolean, "defined">;
107
- valuationInvestmentStrategy: z<boolean, boolean, "defined">;
108
- strategyBusinessTransition: z<boolean, boolean, "defined">;
109
- industryCompetitionMoat: z<boolean, boolean, "defined">;
110
- businessDecompositionOrderQuality: z<boolean, boolean, "defined">;
98
+ [k: string]: z<boolean, boolean, "defined">;
111
99
  }>>, "defined">;
112
100
  fuyaoCredentialRef: z<string, string, "defined">;
113
101
  retriever: z<Schemastery.ObjectS<NoInfer<{
@@ -190,21 +178,9 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
190
178
  }>>, Schemastery.ObjectT<NoInfer<{
191
179
  customPersona: z<string, string, "defined">;
192
180
  selectedSkills: z<Schemastery.ObjectS<NoInfer<{
193
- buffettFramework: z<boolean, boolean, "defined">;
194
- financialHealth: z<boolean, boolean, "defined">;
195
- riskWarningCatalysts: z<boolean, boolean, "defined">;
196
- valuationInvestmentStrategy: z<boolean, boolean, "defined">;
197
- strategyBusinessTransition: z<boolean, boolean, "defined">;
198
- industryCompetitionMoat: z<boolean, boolean, "defined">;
199
- businessDecompositionOrderQuality: z<boolean, boolean, "defined">;
181
+ [k: string]: z<boolean, boolean, "defined">;
200
182
  }>>, Schemastery.ObjectT<NoInfer<{
201
- buffettFramework: z<boolean, boolean, "defined">;
202
- financialHealth: z<boolean, boolean, "defined">;
203
- riskWarningCatalysts: z<boolean, boolean, "defined">;
204
- valuationInvestmentStrategy: z<boolean, boolean, "defined">;
205
- strategyBusinessTransition: z<boolean, boolean, "defined">;
206
- industryCompetitionMoat: z<boolean, boolean, "defined">;
207
- businessDecompositionOrderQuality: z<boolean, boolean, "defined">;
183
+ [k: string]: z<boolean, boolean, "defined">;
208
184
  }>>, "defined">;
209
185
  fuyaoCredentialRef: z<string, string, "defined">;
210
186
  retriever: z<Schemastery.ObjectS<NoInfer<{
package/lib/index.js CHANGED
@@ -13,7 +13,7 @@ import { registerChartTool } from './chart/tool.js';
13
13
  import { createChartEventPublisher } from './chart/events.js';
14
14
  import { registerRootToolPolicy, rootPolicyProbes } from './agents/root-tool-policy.js';
15
15
  import { registerBashGuard } from './agents/bash-guard.js';
16
- import { registerRootSelectedSkills } from './agents/selected-skills-provider.js';
16
+ import { registerRootSelectedSkills, SELECTED_SKILL_CATALOG } from './agents/selected-skills-provider.js';
17
17
  import { ChartSourceTokenStore, registerChartSourceTool } from './chart/source-token.js';
18
18
  import { ChartArtifactRegistry } from './chart/artifact-ref.js';
19
19
  import { WebRetriever } from './web-retriever/retriever.js';
@@ -131,23 +131,13 @@ const RetrieverSchema = z.object({
131
131
  paddleOcr: PaddleOcrSchema.default({ ...PADDLE_OCR_DEFAULTS })
132
132
  .description('PaddleOCR 文档解析(ocr 工具)配置;Token 走 credentials 引用 PADDLE_OCR_TOKEN'),
133
133
  });
134
- const SelectedSkillsSchema = z.object({
135
- buffettFramework: z.boolean().default(false).description('Enable the Finterm Buffett framework experiment for the Capital root Agent'),
136
- financialHealth: z.boolean().default(false).description('Enable the China-stock financial health experiment for the Capital root Agent'),
137
- riskWarningCatalysts: z.boolean().default(false).description('Enable the China-stock risk and catalyst monitoring experiment for the Capital root Agent'),
138
- valuationInvestmentStrategy: z.boolean().default(false).description('Enable the China-stock valuation experiment for the Capital root Agent'),
139
- strategyBusinessTransition: z.boolean().default(false).description('Enable the China-stock business transition experiment for the Capital root Agent'),
140
- industryCompetitionMoat: z.boolean().default(false).description('Enable the China-stock industry and competition experiment for the Capital root Agent'),
141
- businessDecompositionOrderQuality: z.boolean().default(false).description('Enable the China-stock order quality experiment for the Capital root Agent'),
142
- }).default({
143
- buffettFramework: false,
144
- financialHealth: false,
145
- riskWarningCatalysts: false,
146
- valuationInvestmentStrategy: false,
147
- strategyBusinessTransition: false,
148
- industryCompetitionMoat: false,
149
- businessDecompositionOrderQuality: false,
150
- });
134
+ // 开关清单只有一处来源:selected-skills 的 catalog。卡片那侧(capital-config/index.js)一直按
135
+ // catalog 现算,主插件 Config 却手抄过一份 key 列表——接第三颗快照时这两处就漂了(默认值在
136
+ // 条目→主插件 边界被静默丢弃,表现是卡片能拨、运行期读不到)。新增快照因此不必再动 src/。
137
+ const SelectedSkillsSchema = z.object(Object.fromEntries(SELECTED_SKILL_CATALOG.map(({ key, name }) => [
138
+ key,
139
+ z.boolean().default(false).description(`Enable the community experiment "${name}" for the Capital root Agent`),
140
+ ]))).default(Object.fromEntries(SELECTED_SKILL_CATALOG.map(({ key }) => [key, false])));
151
141
  /** DSH 0.1.2-rc.1 configuration schema. */
152
142
  export const Config = z.object({
153
143
  customPersona: z.string()
@@ -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.0";
9
+ export declare const LOCAL_FETCH_CLIENT_VERSION = "2.7.1";
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.0';
10
+ export const LOCAL_FETCH_CLIENT_VERSION = '2.7.1';
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.0";
55
+ export declare const WIND_CLIENT_VERSION = "2.7.1";
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.0';
38
+ export const WIND_CLIENT_VERSION = '2.7.1';
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.0",
3
+ "version": "2.7.1",
4
4
  "description": "Capital Generation:面向中国散户的 AI 投资助手插件(Capital mode Agent Preset)",
5
5
  "icon": "assets/cg-icon.png",
6
6
  "author": "v587d",
@@ -36,6 +36,7 @@
36
36
  "selected-skills/README.md",
37
37
  "selected-skills/investment-skills",
38
38
  "selected-skills/china-stock-research-skills",
39
+ "selected-skills/InvestSkill",
39
40
  "cordis.patch.yml",
40
41
  "assets/cg-icon.png",
41
42
  "README.md",