echopai 2.6.1 → 2.8.0
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.
- package/dist/bin.js +463 -757
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -15,8 +15,8 @@ var OPERATIONS = {
|
|
|
15
15
|
cliName: "agent session-end",
|
|
16
16
|
method: "POST",
|
|
17
17
|
path: "/v1/agent/session/{id}/end",
|
|
18
|
-
description: "
|
|
19
|
-
summary: "
|
|
18
|
+
description: "Closes a session opened by `/v1/agent/session/start` and commits its final usage.",
|
|
19
|
+
summary: "Close a billable agent session.",
|
|
20
20
|
positional: [
|
|
21
21
|
"id"
|
|
22
22
|
],
|
|
@@ -50,8 +50,8 @@ var OPERATIONS = {
|
|
|
50
50
|
cliName: "agent session-start",
|
|
51
51
|
method: "POST",
|
|
52
52
|
path: "/v1/agent/session/start",
|
|
53
|
-
description: "
|
|
54
|
-
summary: "
|
|
53
|
+
description: "Opens a billable session for an agent credential and returns a session_id that groups subsequent calls into a single billable unit. Requires an `Idempotency-Key` header.",
|
|
54
|
+
summary: "Open a billable agent session.",
|
|
55
55
|
positional: [],
|
|
56
56
|
outputDefault: "json",
|
|
57
57
|
pagination: "none",
|
|
@@ -115,8 +115,8 @@ var OPERATIONS = {
|
|
|
115
115
|
cliName: "agent session-usage",
|
|
116
116
|
method: "GET",
|
|
117
117
|
path: "/v1/agent/session/{id}/usage",
|
|
118
|
-
description: "
|
|
119
|
-
summary: "Get cumulative usage
|
|
118
|
+
description: "Returns the cumulative billable call count and per-scope quota consumption for the given session.",
|
|
119
|
+
summary: "Get cumulative usage for an agent session.",
|
|
120
120
|
positional: [
|
|
121
121
|
"id"
|
|
122
122
|
],
|
|
@@ -150,8 +150,8 @@ var OPERATIONS = {
|
|
|
150
150
|
cliName: "announcements detail",
|
|
151
151
|
method: "GET",
|
|
152
152
|
path: "/v1/announcements/{announcement_id}",
|
|
153
|
-
description: "
|
|
154
|
-
summary: "
|
|
153
|
+
description: "Returns the full content of one announcement: body (markdown and plain text), metadata, and parse status.",
|
|
154
|
+
summary: "Get a single announcement by id.",
|
|
155
155
|
positional: [
|
|
156
156
|
"announcement_id"
|
|
157
157
|
],
|
|
@@ -185,8 +185,8 @@ var OPERATIONS = {
|
|
|
185
185
|
cliName: "announcements feed",
|
|
186
186
|
method: "GET",
|
|
187
187
|
path: "/v1/announcements/feed",
|
|
188
|
-
description: "
|
|
189
|
-
summary: "List recent A-share announcements",
|
|
188
|
+
description: "Returns a feed of recent A-share corporate announcements, sorted by publication date descending. Filter by `type` or `since`. Requires the `announcements:read` scope.",
|
|
189
|
+
summary: "List recent A-share announcements.",
|
|
190
190
|
positional: [],
|
|
191
191
|
outputDefault: "json",
|
|
192
192
|
pagination: "offset",
|
|
@@ -233,8 +233,8 @@ var OPERATIONS = {
|
|
|
233
233
|
cliName: "announcements search",
|
|
234
234
|
method: "GET",
|
|
235
235
|
path: "/v1/announcements/search",
|
|
236
|
-
description: "
|
|
237
|
-
summary: "
|
|
236
|
+
description: "Hybrid search over A-share announcements: structured filtering by security name or code, combined with full-text keyword search (over title, AI summary, and the first ~1500 characters of the body). A query containing a 6-digit code or an embedded security name is filtered by that security; remaining free text is ranked by relevance with time decay; a pure code or name lists results by publication date descending. Requires the `announcements:read` scope.",
|
|
237
|
+
summary: "Search A-share announcements.",
|
|
238
238
|
positional: [],
|
|
239
239
|
outputDefault: "json",
|
|
240
240
|
pagination: "offset",
|
|
@@ -293,8 +293,8 @@ var OPERATIONS = {
|
|
|
293
293
|
cliName: "announcements stock",
|
|
294
294
|
method: "GET",
|
|
295
295
|
path: "/v1/announcements/stock",
|
|
296
|
-
description: "
|
|
297
|
-
summary: "List announcements for
|
|
296
|
+
description: "Returns the announcement history for one A-share security over a date window. Accepts a 6-digit code or canonical form (e.g. `SSE:600519`). Requires the `announcements:read` scope.",
|
|
297
|
+
summary: "List announcements for one security.",
|
|
298
298
|
positional: [],
|
|
299
299
|
outputDefault: "json",
|
|
300
300
|
pagination: "offset",
|
|
@@ -352,17 +352,8 @@ var OPERATIONS = {
|
|
|
352
352
|
cliName: "auth whoami",
|
|
353
353
|
method: "GET",
|
|
354
354
|
path: "/v1/auth/whoami",
|
|
355
|
-
description:
|
|
356
|
-
|
|
357
|
-
feature_flags. Any valid JWT can call — no specific scope required.
|
|
358
|
-
|
|
359
|
-
CLI/MCP call this once at startup, cache 5 minutes in-process, and use
|
|
360
|
-
the response to derive \`verbs.available\` (intersection of curated verb
|
|
361
|
-
scopes with token scopes) and to populate \`echopai doctor\` checks.
|
|
362
|
-
|
|
363
|
-
See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §5.1.
|
|
364
|
-
`,
|
|
365
|
-
summary: "Token introspection (CLI/MCP capability discovery)",
|
|
355
|
+
description: "Returns the calling token's kind, scopes, audience, app metadata, rate limit, allowed clients, agent budget (when kind=agent), API version, and feature flags. Any valid token may call this; no specific scope is required. Clients typically call it once at startup and cache the result briefly to determine which commands are available.",
|
|
356
|
+
summary: "Introspect the calling token (capability discovery).",
|
|
366
357
|
positional: [],
|
|
367
358
|
outputDefault: "json",
|
|
368
359
|
pagination: "none",
|
|
@@ -383,8 +374,8 @@ See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §5.1.
|
|
|
383
374
|
cliName: "bars daily",
|
|
384
375
|
method: "GET",
|
|
385
376
|
path: "/v1/bars/daily",
|
|
386
|
-
description: "
|
|
387
|
-
summary: "
|
|
377
|
+
description: "Returns daily open/high/low/close/volume/turnover for one A-share security over a date range (canonical code, e.g. `SSE:600519`). End-of-day data. Requires the `bars:30d` scope (last 30 trading days) or `bars:full` scope (full history).",
|
|
378
|
+
summary: "List daily OHLC bars for one A-share security.",
|
|
388
379
|
positional: [],
|
|
389
380
|
outputDefault: "json",
|
|
390
381
|
pagination: "none",
|
|
@@ -432,8 +423,8 @@ See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §5.1.
|
|
|
432
423
|
cliName: "bars daily-batch",
|
|
433
424
|
method: "GET",
|
|
434
425
|
path: "/v1/bars/daily-batch",
|
|
435
|
-
description: "
|
|
436
|
-
summary: "Batch daily OHLC bars for up to 100
|
|
426
|
+
description: "Returns daily OHLC bars for multiple A-share securities in one call: up to 100 codes and up to a one-year date range. Responses use a partial-success envelope: codes the token may not access are reported in `errors[]`, the rest in `items[]` (with an empty `bars[]` when no data is found), preserving input order. Requires the `bars:30d` or `bars:full` scope.",
|
|
427
|
+
summary: "Batch daily OHLC bars for up to 100 securities.",
|
|
437
428
|
positional: [],
|
|
438
429
|
outputDefault: "json",
|
|
439
430
|
pagination: "none",
|
|
@@ -489,8 +480,8 @@ See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §5.1.
|
|
|
489
480
|
cliName: "bars minute",
|
|
490
481
|
method: "GET",
|
|
491
482
|
path: "/v1/bars/minute",
|
|
492
|
-
description: "
|
|
493
|
-
summary: "
|
|
483
|
+
description: "Returns minute-level OHLC bars for one A-share security on a single trade date (canonical code, e.g. `SSE:600519`). Requires the `bars:30d` or `bars:full` scope.",
|
|
484
|
+
summary: "List minute OHLC bars for one A-share security.",
|
|
494
485
|
positional: [],
|
|
495
486
|
outputDefault: "json",
|
|
496
487
|
pagination: "none",
|
|
@@ -531,8 +522,8 @@ See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §5.1.
|
|
|
531
522
|
cliName: "bars minute-batch",
|
|
532
523
|
method: "GET",
|
|
533
524
|
path: "/v1/bars/minute-batch",
|
|
534
|
-
description: "
|
|
535
|
-
summary: "Batch minute OHLC bars for up to 20
|
|
525
|
+
description: "Returns minute-level OHLC bars for multiple A-share securities in one call: up to 20 codes and up to a 7 calendar-day (~5 trading-day) range. Responses use a partial-success envelope: codes the token may not access are reported in `errors[]`, the rest in `items[]` with a flat `bars[]` array where each bar carries its own `trade_date` for client-side grouping. Requires the `bars:30d` or `bars:full` scope.",
|
|
526
|
+
summary: "Batch minute OHLC bars for up to 20 securities.",
|
|
536
527
|
positional: [],
|
|
537
528
|
outputDefault: "json",
|
|
538
529
|
pagination: "none",
|
|
@@ -583,17 +574,35 @@ See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §5.1.
|
|
|
583
574
|
]
|
|
584
575
|
}
|
|
585
576
|
},
|
|
577
|
+
"capabilities.show": {
|
|
578
|
+
cliKey: "capabilities.show",
|
|
579
|
+
cliName: "capabilities show",
|
|
580
|
+
method: "GET",
|
|
581
|
+
path: "/v1/capabilities",
|
|
582
|
+
description: "Returns the current API spec version plus a machine-readable changelog of capability changes (new endpoints, new fields, behavior fixes), newest first. Check it at session start — or after an unexpected response shape — to discover capabilities added since your integration was written. Free and unauthenticated.",
|
|
583
|
+
summary: "Capability changelog and API version discovery.",
|
|
584
|
+
positional: [],
|
|
585
|
+
outputDefault: "json",
|
|
586
|
+
pagination: "none",
|
|
587
|
+
stream: false,
|
|
588
|
+
billable: false,
|
|
589
|
+
idempotencyRequired: false,
|
|
590
|
+
scopesAny: [],
|
|
591
|
+
sideEffect: "read",
|
|
592
|
+
dryRunSupported: false,
|
|
593
|
+
inputSchema: {
|
|
594
|
+
type: "object",
|
|
595
|
+
properties: {},
|
|
596
|
+
additionalProperties: false
|
|
597
|
+
}
|
|
598
|
+
},
|
|
586
599
|
"concepts.alerts": {
|
|
587
600
|
cliKey: "concepts.alerts",
|
|
588
601
|
cliName: "concepts alerts",
|
|
589
602
|
method: "GET",
|
|
590
603
|
path: "/v1/concepts/alerts",
|
|
591
|
-
description:
|
|
592
|
-
|
|
593
|
-
- limit_up_cluster: limit_up_count >= 3 AND stock_count >= 5
|
|
594
|
-
See PLAN_CONCEPT_INDUSTRY_QUOTE §5.5 "异动检测与推送".
|
|
595
|
-
`,
|
|
596
|
-
summary: "Currently active concept alerts (big_move / limit_up_cluster)",
|
|
604
|
+
description: "Returns the live set of concept alerts. Two rules fire: `big_move` when absolute percent change exceeds 3%, and `limit_up_cluster` when a concept has at least 3 limit-up members across at least 5 member stocks.",
|
|
605
|
+
summary: "List currently active concept alerts.",
|
|
597
606
|
positional: [],
|
|
598
607
|
outputDefault: "json",
|
|
599
608
|
pagination: "none",
|
|
@@ -618,8 +627,8 @@ See PLAN_CONCEPT_INDUSTRY_QUOTE §5.5 "异动检测与推送".
|
|
|
618
627
|
cliName: "concepts alerts-history",
|
|
619
628
|
method: "GET",
|
|
620
629
|
path: "/v1/concepts/alerts/history",
|
|
621
|
-
description: "
|
|
622
|
-
summary: "
|
|
630
|
+
description: "Returns historical concept alert events (default: last 24 hours). Filter by rule (`big_move` / `limit_up_cluster`) and time window. Useful for reviewing how concept activity evolved over a period.",
|
|
631
|
+
summary: "List recent concept alert history.",
|
|
623
632
|
positional: [],
|
|
624
633
|
outputDefault: "json",
|
|
625
634
|
pagination: "none",
|
|
@@ -668,10 +677,8 @@ See PLAN_CONCEPT_INDUSTRY_QUOTE §5.5 "异动检测与推送".
|
|
|
668
677
|
cliName: "concepts daily-bars",
|
|
669
678
|
method: "GET",
|
|
670
679
|
path: "/v1/concepts/{concept_id}/daily-bars",
|
|
671
|
-
description:
|
|
672
|
-
|
|
673
|
-
`,
|
|
674
|
-
summary: "Concept index daily bars (chain-linked equal-weight, base 1000)",
|
|
680
|
+
description: "Returns daily OHLC for a concept index (index points, not an average of member stock prices), along with breadth fields and a backfill flag. The concept index is a chain-linked equal-weight return series with a base of 1000.",
|
|
681
|
+
summary: "List daily bars for a concept index.",
|
|
675
682
|
positional: [
|
|
676
683
|
"concept_id"
|
|
677
684
|
],
|
|
@@ -716,8 +723,8 @@ breadth fields, and is_backfilled flag. See PLAN §5.4 algorithm.
|
|
|
716
723
|
cliName: "concepts list",
|
|
717
724
|
method: "GET",
|
|
718
725
|
path: "/v1/concepts",
|
|
719
|
-
description: "
|
|
720
|
-
summary: "List concepts with live snapshot
|
|
726
|
+
description: "Lists market concepts (themes/sectors) joined with their latest real-time snapshot, falling back to the last close and then to recent daily data when live ticks are unavailable. Each item carries a `_source` freshness indicator. Live fields include percent change, index value, advancing/declining counts, limit-up count, turnover amount, 3-minute momentum, and `main_net_in` (net main-capital inflow in CNY, which may be negative for net outflow and null when unavailable). The concept index is a chain-linked equal-weight return series with a base of 1000. During the 9:00–9:14 pre-open window, live data is suppressed and a loading state is returned.",
|
|
727
|
+
summary: "List concepts with their live snapshot.",
|
|
721
728
|
positional: [],
|
|
722
729
|
outputDefault: "json",
|
|
723
730
|
pagination: "none",
|
|
@@ -773,8 +780,8 @@ breadth fields, and is_backfilled flag. See PLAN §5.4 algorithm.
|
|
|
773
780
|
cliName: "concepts minute-bars",
|
|
774
781
|
method: "GET",
|
|
775
782
|
path: "/v1/concepts/{concept_id}/minute-bars",
|
|
776
|
-
description: "
|
|
777
|
-
summary: "
|
|
783
|
+
description: "Returns minute-level OHLC for a concept index (chain-linked equal-weight return series, base 1000), up to 7 days per request.",
|
|
784
|
+
summary: "List minute bars for a concept index.",
|
|
778
785
|
positional: [
|
|
779
786
|
"concept_id"
|
|
780
787
|
],
|
|
@@ -819,10 +826,8 @@ breadth fields, and is_backfilled flag. See PLAN §5.4 algorithm.
|
|
|
819
826
|
cliName: "concepts news",
|
|
820
827
|
method: "GET",
|
|
821
828
|
path: "/v1/concepts/{concept_id}/news",
|
|
822
|
-
description:
|
|
823
|
-
|
|
824
|
-
`,
|
|
825
|
-
summary: "Related news matching concept name (ILIKE)",
|
|
829
|
+
description: "Returns recent news whose title or body mentions the concept's name. Use it to see what is currently driving a theme.",
|
|
830
|
+
summary: "List news related to a concept.",
|
|
826
831
|
positional: [
|
|
827
832
|
"concept_id"
|
|
828
833
|
],
|
|
@@ -869,8 +874,8 @@ concept name and full_name. Long-term: news AI tagging.
|
|
|
869
874
|
cliName: "concepts show",
|
|
870
875
|
method: "GET",
|
|
871
876
|
path: "/v1/concepts/{concept_id}",
|
|
872
|
-
description: "
|
|
873
|
-
summary: "
|
|
877
|
+
description: "Returns detail for one concept: metadata (full name, source, status, approval date, first-listed date) plus its current member securities with their latest snapshots.",
|
|
878
|
+
summary: "Get concept detail with member securities.",
|
|
874
879
|
positional: [
|
|
875
880
|
"concept_id"
|
|
876
881
|
],
|
|
@@ -905,8 +910,8 @@ concept name and full_name. Long-term: news AI tagging.
|
|
|
905
910
|
cliName: "concepts snapshot",
|
|
906
911
|
method: "GET",
|
|
907
912
|
path: "/v1/concepts/snapshot",
|
|
908
|
-
description: "
|
|
909
|
-
summary: "Bulk
|
|
913
|
+
description: "Returns real-time snapshots for concepts, with two modes. With `codes=`, each requested concept id is resolved via real-time → last-close → recent-daily fallback so every requested id is populated. Without `codes`, it returns a best-effort dump of all concepts that currently have a real-time or last-close snapshot; concepts absent from both are not backfilled (use `GET /v1/concepts` if you need every known concept). Each item carries a `_source` freshness indicator. During the 9:00–9:14 pre-open window, live data is suppressed and an empty list is returned.",
|
|
914
|
+
summary: "Bulk real-time snapshot of concepts.",
|
|
910
915
|
positional: [],
|
|
911
916
|
outputDefault: "json",
|
|
912
917
|
pagination: "none",
|
|
@@ -936,8 +941,8 @@ concept name and full_name. Long-term: news AI tagging.
|
|
|
936
941
|
cliName: "concepts views",
|
|
937
942
|
method: "GET",
|
|
938
943
|
path: "/v1/concepts/{concept_id}/views",
|
|
939
|
-
description: "
|
|
940
|
-
summary: "
|
|
944
|
+
description: "Returns analyst views linked to this concept (with AI processing complete), sorted by publication date descending.",
|
|
945
|
+
summary: "List analyst views associated with a concept.",
|
|
941
946
|
positional: [
|
|
942
947
|
"concept_id"
|
|
943
948
|
],
|
|
@@ -977,25 +982,8 @@ concept name and full_name. Long-term: news AI tagging.
|
|
|
977
982
|
cliName: "digest get",
|
|
978
983
|
method: "GET",
|
|
979
984
|
path: "/v1/digest/{code}",
|
|
980
|
-
description:
|
|
981
|
-
|
|
982
|
-
market sentiment context, and supplementary news.
|
|
983
|
-
Partial-failure tolerant:
|
|
984
|
-
each bucket is independently fetched and per-bucket failures surface
|
|
985
|
-
in \`meta.partial_failures[]\` rather than poisoning the response. If
|
|
986
|
-
every sub-bucket fails the endpoint returns 502.
|
|
987
|
-
|
|
988
|
-
Bucket scopes are checked *per bucket* (not at gateway level): a
|
|
989
|
-
token with only \`views:read\` gets the views bucket populated and the
|
|
990
|
-
rest reported as \`scope_insufficient\` partial failures. This mirrors
|
|
991
|
-
the CLI fan-out contract exactly so \`echopai digest\` can either call
|
|
992
|
-
this endpoint (preferred, single round-trip) or fall back to local
|
|
993
|
-
fan-out without behavior drift.
|
|
994
|
-
|
|
995
|
-
See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §3.3 (digest spec) and §11
|
|
996
|
-
Phase 5.2 (server endpoint).
|
|
997
|
-
`,
|
|
998
|
-
summary: "One-shot research digest for a single security (composite)",
|
|
985
|
+
description: "Composite endpoint that, in a single call, returns separated sections for one security: analyst views (the primary research source), a real-time quote, a valuation snapshot (PE/PB/PS, turnover rate, dividend yield, volume ratio, and ~14 fields in total), market sentiment context, and supplementary news. Each section is fetched independently and per-section failures are reported in `meta.partial_failures[]` instead of failing the whole call; the endpoint returns 502 only if every section fails. Scopes are enforced per section, so a token with only `views:read` receives the views section and sees the rest reported as scope-insufficient. Use this when you want a single broad overview of a security (canonical code, e.g. `SSE:600519`).",
|
|
986
|
+
summary: "Build a one-shot research digest for one security.",
|
|
999
987
|
positional: [
|
|
1000
988
|
"code"
|
|
1001
989
|
],
|
|
@@ -1049,8 +1037,8 @@ Phase 5.2 (server endpoint).
|
|
|
1049
1037
|
cliName: "financials pit",
|
|
1050
1038
|
method: "GET",
|
|
1051
1039
|
path: "/v1/financials/pit",
|
|
1052
|
-
description: "
|
|
1053
|
-
summary: "
|
|
1040
|
+
description: "Returns the most recent financial report that was publicly available on a given date for one A-share security (canonical code, e.g. `SSE:600519`) — i.e. announcement date on or before `date`, with a conservative 90-day fallback when the announcement date is unknown. Designed to avoid look-ahead bias in backtests and quantitative strategies. Fields include EPS (basic / non-recurring / diluted), BPS, ROE, gross margin, revenue, net profit, total assets, and parent-company equity (~25 core fields).",
|
|
1041
|
+
summary: "Get point-in-time fundamentals for one security at a date.",
|
|
1054
1042
|
positional: [],
|
|
1055
1043
|
outputDefault: "json",
|
|
1056
1044
|
pagination: "none",
|
|
@@ -1089,8 +1077,8 @@ Phase 5.2 (server endpoint).
|
|
|
1089
1077
|
cliName: "financials quote-snapshot",
|
|
1090
1078
|
method: "GET",
|
|
1091
1079
|
path: "/v1/financials/quote-snapshot",
|
|
1092
|
-
description: "
|
|
1093
|
-
summary: "
|
|
1080
|
+
description: "Returns a one-stop valuation snapshot (14 fields) for one A-share security (canonical code, e.g. `SSE:600519`), combining real-time prices with point-in-time fundamentals so figures are free of look-ahead bias. Fields: valuation (`pe`, `pe_ttm`, `pb`, `ps`, `ps_ttm`); share counts in 10k shares (`total_share`, `float_share`, `free_share`); market cap in 10k CNY (`total_mv`, `circ_mv`); liquidity (`turnover_rate`, `turnover_rate_f` in %, `volume_ratio` as a multiple); and dividend yield (`dv_ratio`, `dv_ttm` in %). Leave `date` empty for a real-time snapshot, or pass `date=YYYY-MM-DD` to value as of that day's close (useful for historical checks and backtests).",
|
|
1081
|
+
summary: "Get a real-time valuation snapshot for one security.",
|
|
1094
1082
|
positional: [],
|
|
1095
1083
|
outputDefault: "json",
|
|
1096
1084
|
pagination: "none",
|
|
@@ -1130,8 +1118,8 @@ Phase 5.2 (server endpoint).
|
|
|
1130
1118
|
cliName: "financials reports",
|
|
1131
1119
|
method: "GET",
|
|
1132
1120
|
path: "/v1/financials/reports",
|
|
1133
|
-
description: "
|
|
1134
|
-
summary: "
|
|
1121
|
+
description: "Returns core indicators for the most recent N financial reports of one A-share security (EPS/BPS/ROE, gross margin, revenue, net profit, total assets, parent equity, operating cash flow, total shares, and ~25 fields in total). Filter by `kind` for quarterly / interim / annual reports. Each report's `announce_date` indicates when it became publicly visible, which is useful for point-in-time analysis. Note: `kind=preliminary` does not exist as a separate report row — earnings forecasts and flash reports are exposed as metric fields (e.g. `forecast_ni_lower`, `forecast_ni_upper`, `express_ni_parent`, `express_revenue`) via `financials.series`, so `kind=preliminary` returns an empty list with an explanatory note.",
|
|
1122
|
+
summary: "List recent financial reports for one security.",
|
|
1135
1123
|
positional: [],
|
|
1136
1124
|
outputDefault: "json",
|
|
1137
1125
|
pagination: "none",
|
|
@@ -1182,8 +1170,8 @@ Phase 5.2 (server endpoint).
|
|
|
1182
1170
|
cliName: "financials series",
|
|
1183
1171
|
method: "GET",
|
|
1184
1172
|
path: "/v1/financials/series",
|
|
1185
|
-
description: "
|
|
1186
|
-
summary: "
|
|
1173
|
+
description: "Returns the historical time series of a single financial metric for one A-share security, ordered by reporting period. `metric` is an indicator field name (e.g. `roe_simple`, `revenue`, `ni_parent`, `debt_asset_ratio`, `gross_margin`, `eps_basic`; ~150 metrics available). Use it to chart a multi-year trend for one company or to compare the same metric across several securities.",
|
|
1174
|
+
summary: "Get a time series of one financial metric.",
|
|
1187
1175
|
positional: [],
|
|
1188
1176
|
outputDefault: "json",
|
|
1189
1177
|
pagination: "none",
|
|
@@ -1241,8 +1229,8 @@ Phase 5.2 (server endpoint).
|
|
|
1241
1229
|
cliName: "index daily-bars",
|
|
1242
1230
|
method: "GET",
|
|
1243
1231
|
path: "/v1/index/bars/daily",
|
|
1244
|
-
description: "
|
|
1245
|
-
summary: "
|
|
1232
|
+
description: "Returns daily OHLC for one A-share index (e.g. 上证综指 `SSE:000001`, 深证成指 `SZSE:399001`, 沪深300 `SSE:000300`, 北证50 `BSE:899050`, CSI series such as `CSI:000922`). Same semantics as `/v1/bars/daily`, but indices have no stock-specific fields such as turnover rate or suspension flag.",
|
|
1233
|
+
summary: "List daily OHLC bars for one A-share index.",
|
|
1246
1234
|
positional: [],
|
|
1247
1235
|
outputDefault: "json",
|
|
1248
1236
|
pagination: "none",
|
|
@@ -1290,8 +1278,8 @@ Phase 5.2 (server endpoint).
|
|
|
1290
1278
|
cliName: "index minute-bars",
|
|
1291
1279
|
method: "GET",
|
|
1292
1280
|
path: "/v1/index/bars/minute",
|
|
1293
|
-
description: "
|
|
1294
|
-
summary: "
|
|
1281
|
+
description: "Returns 1-minute OHLC for one A-share index over a date range of up to 7 days. Each bar includes bar time, trade date, OHLC, volume, amount, and percent change.",
|
|
1282
|
+
summary: "List minute OHLC bars for one A-share index.",
|
|
1295
1283
|
positional: [],
|
|
1296
1284
|
outputDefault: "json",
|
|
1297
1285
|
pagination: "none",
|
|
@@ -1337,8 +1325,8 @@ Phase 5.2 (server endpoint).
|
|
|
1337
1325
|
cliName: "index snapshot",
|
|
1338
1326
|
method: "GET",
|
|
1339
1327
|
path: "/v1/index/snapshot",
|
|
1340
|
-
description: "Returns the latest real-time snapshot for the 172 indices that
|
|
1341
|
-
summary: "
|
|
1328
|
+
description: "Returns the latest real-time snapshot for the 172 A-share indices that have a live quote feed (SSE / SZSE / BSE, including 北证50 `BSE:899050`). The snapshot refreshes roughly every 15 seconds during market hours; outside trading hours the last intraday snapshot is returned. Use `codes` (canonical format, e.g. `SSE:000001`) to narrow to a subset, or omit it to receive all indices. Note: CSI-series indices (e.g. `CSI:000922`) have no live quote feed and are not returned here. Requires a `quote:l1`, `quote:l2`, or `quote:delayed` scope.",
|
|
1329
|
+
summary: "Snapshot real-time quotes for A-share indices.",
|
|
1342
1330
|
positional: [],
|
|
1343
1331
|
outputDefault: "json",
|
|
1344
1332
|
pagination: "none",
|
|
@@ -1364,197 +1352,13 @@ Phase 5.2 (server endpoint).
|
|
|
1364
1352
|
additionalProperties: false
|
|
1365
1353
|
}
|
|
1366
1354
|
},
|
|
1367
|
-
"industries.alerts": {
|
|
1368
|
-
cliKey: "industries.alerts",
|
|
1369
|
-
cliName: "industries alerts",
|
|
1370
|
-
method: "GET",
|
|
1371
|
-
path: "/v1/industries/alerts",
|
|
1372
|
-
description: "Currently active industry alerts (big_move / limit_up_cluster). Same rule set as concepts.",
|
|
1373
|
-
summary: "Currently active industry alerts",
|
|
1374
|
-
positional: [],
|
|
1375
|
-
outputDefault: "json",
|
|
1376
|
-
pagination: "none",
|
|
1377
|
-
stream: false,
|
|
1378
|
-
billable: false,
|
|
1379
|
-
idempotencyRequired: false,
|
|
1380
|
-
scopesAny: [
|
|
1381
|
-
"quote:l1",
|
|
1382
|
-
"quote:l2",
|
|
1383
|
-
"quote:delayed"
|
|
1384
|
-
],
|
|
1385
|
-
sideEffect: "read",
|
|
1386
|
-
dryRunSupported: false,
|
|
1387
|
-
inputSchema: {
|
|
1388
|
-
type: "object",
|
|
1389
|
-
properties: {},
|
|
1390
|
-
additionalProperties: false
|
|
1391
|
-
}
|
|
1392
|
-
},
|
|
1393
|
-
"industries.daily-bars": {
|
|
1394
|
-
cliKey: "industries.daily-bars",
|
|
1395
|
-
cliName: "industries daily-bars",
|
|
1396
|
-
method: "GET",
|
|
1397
|
-
path: "/v1/industries/{key}/daily-bars",
|
|
1398
|
-
description: "Industry index daily OHLC (chain-linked equal-weight, base = 1000). Path key format `<sw_industry_code>:<sw_level>` (e.g. `401001:1`).",
|
|
1399
|
-
summary: "Industry index daily bars",
|
|
1400
|
-
positional: [
|
|
1401
|
-
"key"
|
|
1402
|
-
],
|
|
1403
|
-
outputDefault: "json",
|
|
1404
|
-
pagination: "none",
|
|
1405
|
-
stream: false,
|
|
1406
|
-
billable: true,
|
|
1407
|
-
idempotencyRequired: false,
|
|
1408
|
-
scopesAny: [
|
|
1409
|
-
"bars:read"
|
|
1410
|
-
],
|
|
1411
|
-
sideEffect: "read",
|
|
1412
|
-
dryRunSupported: false,
|
|
1413
|
-
inputSchema: {
|
|
1414
|
-
type: "object",
|
|
1415
|
-
properties: {
|
|
1416
|
-
key: {
|
|
1417
|
-
type: "string",
|
|
1418
|
-
description: "Industry key in `<sw_industry_code>:<sw_level>` format (e.g. `401001:1`).",
|
|
1419
|
-
example: "401001:1"
|
|
1420
|
-
},
|
|
1421
|
-
from: {
|
|
1422
|
-
type: "string",
|
|
1423
|
-
format: "date",
|
|
1424
|
-
description: "Window start. For daily/minute bars: ISO date `YYYY-MM-DD`. For alerts history: Unix milliseconds (default = now - 24h)."
|
|
1425
|
-
},
|
|
1426
|
-
to: {
|
|
1427
|
-
type: "string",
|
|
1428
|
-
format: "date",
|
|
1429
|
-
description: "Window end. For daily/minute bars: ISO date `YYYY-MM-DD`. For alerts history: Unix milliseconds (default = now)."
|
|
1430
|
-
}
|
|
1431
|
-
},
|
|
1432
|
-
additionalProperties: false,
|
|
1433
|
-
required: [
|
|
1434
|
-
"key",
|
|
1435
|
-
"from",
|
|
1436
|
-
"to"
|
|
1437
|
-
]
|
|
1438
|
-
}
|
|
1439
|
-
},
|
|
1440
|
-
"industries.list": {
|
|
1441
|
-
cliKey: "industries.list",
|
|
1442
|
-
cliName: "industries list",
|
|
1443
|
-
method: "GET",
|
|
1444
|
-
path: "/v1/industries",
|
|
1445
|
-
description: "Industry index list joining CH `v_industry_meta` with Redis snapshot.\n申万一级 (level=1) ≈ 127 industries, 申万二级 (level=2) ≈ 348.\nChain-linked equal-weight algorithm identical to concepts (PLAN §5.4).\n\nRead order per industry (mirrors `/v1/concepts`, PR #442):\n 1. `industry_snapshots:latest` (hot, TTL 5min)\n 2. `industry_snapshots:last_close` (warm, TTL 7d)\n 3. CH `v_industry_daily_bars` argMax\n9:00–9:14 reset window suppresses hot+warm (loading state).\nEach item carries `_source` ∈ {`latest`, `last_close`, `ch_daily`, `miss`}.\n",
|
|
1446
|
-
summary: "List industries (申万 L1/L2) with hot/warm fallback",
|
|
1447
|
-
positional: [],
|
|
1448
|
-
outputDefault: "json",
|
|
1449
|
-
pagination: "none",
|
|
1450
|
-
stream: false,
|
|
1451
|
-
billable: true,
|
|
1452
|
-
idempotencyRequired: false,
|
|
1453
|
-
scopesAny: [
|
|
1454
|
-
"quote:l1",
|
|
1455
|
-
"quote:l2",
|
|
1456
|
-
"quote:delayed"
|
|
1457
|
-
],
|
|
1458
|
-
sideEffect: "read",
|
|
1459
|
-
dryRunSupported: false,
|
|
1460
|
-
inputSchema: {
|
|
1461
|
-
type: "object",
|
|
1462
|
-
properties: {
|
|
1463
|
-
level: {
|
|
1464
|
-
type: "integer",
|
|
1465
|
-
enum: [
|
|
1466
|
-
1,
|
|
1467
|
-
2
|
|
1468
|
-
],
|
|
1469
|
-
default: 1,
|
|
1470
|
-
description: "申万 industry level (1 or 2)."
|
|
1471
|
-
},
|
|
1472
|
-
limit: {
|
|
1473
|
-
type: "integer",
|
|
1474
|
-
minimum: 1,
|
|
1475
|
-
maximum: 1000,
|
|
1476
|
-
default: 500,
|
|
1477
|
-
description: "Maximum number of items to return."
|
|
1478
|
-
}
|
|
1479
|
-
},
|
|
1480
|
-
additionalProperties: false
|
|
1481
|
-
}
|
|
1482
|
-
},
|
|
1483
|
-
"industries.show": {
|
|
1484
|
-
cliKey: "industries.show",
|
|
1485
|
-
cliName: "industries show",
|
|
1486
|
-
method: "GET",
|
|
1487
|
-
path: "/v1/industries/{key}",
|
|
1488
|
-
description: "Path key format: `<sw_industry_code>:<sw_level>` (e.g. `401001:1`).",
|
|
1489
|
-
summary: "Industry detail (meta + today members)",
|
|
1490
|
-
positional: [
|
|
1491
|
-
"key"
|
|
1492
|
-
],
|
|
1493
|
-
outputDefault: "json",
|
|
1494
|
-
pagination: "none",
|
|
1495
|
-
stream: false,
|
|
1496
|
-
billable: true,
|
|
1497
|
-
idempotencyRequired: false,
|
|
1498
|
-
scopesAny: [
|
|
1499
|
-
"quote:l1",
|
|
1500
|
-
"quote:l2",
|
|
1501
|
-
"quote:delayed"
|
|
1502
|
-
],
|
|
1503
|
-
sideEffect: "read",
|
|
1504
|
-
dryRunSupported: false,
|
|
1505
|
-
inputSchema: {
|
|
1506
|
-
type: "object",
|
|
1507
|
-
properties: {
|
|
1508
|
-
key: {
|
|
1509
|
-
type: "string",
|
|
1510
|
-
description: "Industry key in `<sw_industry_code>:<sw_level>` format (e.g. `401001:1`).",
|
|
1511
|
-
example: "401001:1"
|
|
1512
|
-
}
|
|
1513
|
-
},
|
|
1514
|
-
additionalProperties: false,
|
|
1515
|
-
required: [
|
|
1516
|
-
"key"
|
|
1517
|
-
]
|
|
1518
|
-
}
|
|
1519
|
-
},
|
|
1520
|
-
"industries.snapshot": {
|
|
1521
|
-
cliKey: "industries.snapshot",
|
|
1522
|
-
cliName: "industries snapshot",
|
|
1523
|
-
method: "GET",
|
|
1524
|
-
path: "/v1/industries/snapshot",
|
|
1525
|
-
description: "Mirrors `/v1/concepts/snapshot` contract (PR #442 review 二轮):\n\n- **With `codes=`** (per-key completeness): hot → warm → CH fallback\n per industry; missing keys populated.\n- **Without `codes`** (best-effort dump): union of\n `industry_snapshots:latest` and `industry_snapshots:last_close`\n Redis hashes. Missing industries are **not** backfilled from CH; use\n GET `/v1/industries` for a fully populated list.\n\n9:00–9:14 reset window suppresses both Redis hashes and CH fallback.\nEach item carries `_source` ∈ {`latest`, `last_close`, `ch_daily`}.\n申万一级 (level=1) ≈ 127 industries, 申万二级 (level=2) ≈ 348.\n",
|
|
1526
|
-
summary: "Bulk Redis snapshot of industries (hot/warm union)",
|
|
1527
|
-
positional: [],
|
|
1528
|
-
outputDefault: "json",
|
|
1529
|
-
pagination: "none",
|
|
1530
|
-
stream: false,
|
|
1531
|
-
billable: true,
|
|
1532
|
-
idempotencyRequired: false,
|
|
1533
|
-
scopesAny: [
|
|
1534
|
-
"quote:l1",
|
|
1535
|
-
"quote:l2",
|
|
1536
|
-
"quote:delayed"
|
|
1537
|
-
],
|
|
1538
|
-
sideEffect: "read",
|
|
1539
|
-
dryRunSupported: false,
|
|
1540
|
-
inputSchema: {
|
|
1541
|
-
type: "object",
|
|
1542
|
-
properties: {
|
|
1543
|
-
codes: {
|
|
1544
|
-
type: "string",
|
|
1545
|
-
description: "Comma-separated `sw_code:level` (e.g. `401001:1,401002:1`); omit for best-effort Redis union."
|
|
1546
|
-
}
|
|
1547
|
-
},
|
|
1548
|
-
additionalProperties: false
|
|
1549
|
-
}
|
|
1550
|
-
},
|
|
1551
1355
|
"limit-up.analysis": {
|
|
1552
1356
|
cliKey: "limit-up.analysis",
|
|
1553
1357
|
cliName: "limit-up analysis",
|
|
1554
1358
|
method: "GET",
|
|
1555
1359
|
path: "/v1/limit-up/analysis",
|
|
1556
|
-
description:
|
|
1557
|
-
summary: "
|
|
1360
|
+
description: "Returns LLM-generated attribution for each limit-up stock: the leading theme (`leading_concept`), concept tags, and a reason explaining why it hit the limit. Themes are inferred by an LLM from the latest research, institutional views, and news, so they may include brand-new themes; results refresh automatically at six points each trading day, with later runs refining earlier ones. This complements the limit-up pool, which tells you which stocks limited up; this endpoint tells you why and under which theme. Note: when `trade_date` is omitted, the latest attributed trading day is returned — before today's first run completes (around 09:47 Beijing time) this may be the previous trading day rather than empty, so pass an explicit `trade_date` for today and verify the `trade_date` / `generated_at` fields. Requires the `market:read` scope or any `quote:*` scope.",
|
|
1361
|
+
summary: "Get LLM attribution for limit-up stocks.",
|
|
1558
1362
|
positional: [],
|
|
1559
1363
|
outputDefault: "json",
|
|
1560
1364
|
pagination: "none",
|
|
@@ -1586,8 +1390,8 @@ Phase 5.2 (server endpoint).
|
|
|
1586
1390
|
cliName: "limit-up history",
|
|
1587
1391
|
method: "GET",
|
|
1588
1392
|
path: "/v1/limit-up/history",
|
|
1589
|
-
description: "
|
|
1590
|
-
summary: "A-share limit-up daily trend
|
|
1393
|
+
description: "Returns the daily limit-up trend over the last N trading days: per-day limit-up count, highest consecutive-board height, and seal-break count. Sorted by trade date ascending (oldest first). Requires a `quote:*` scope.",
|
|
1394
|
+
summary: "Get the A-share limit-up daily trend.",
|
|
1591
1395
|
positional: [],
|
|
1592
1396
|
outputDefault: "json",
|
|
1593
1397
|
pagination: "none",
|
|
@@ -1620,8 +1424,8 @@ Phase 5.2 (server endpoint).
|
|
|
1620
1424
|
cliName: "limit-up pool",
|
|
1621
1425
|
method: "GET",
|
|
1622
1426
|
path: "/v1/limit-up/pool",
|
|
1623
|
-
description: "
|
|
1624
|
-
summary: "A-share limit-up pool
|
|
1427
|
+
description: "Returns per-stock detail for the limit-up pool on the current (or specified `trade_date`) trading day: first/last seal time, final percent change, seal amount and seal volume, number of times the seal broke, consecutive limit-up days, in-pool statistics over N days, one-line-board flag, current status (limit_up / broken), and sector classification. Sorted by consecutive limit-up days, then in-pool board count, then seal amount (all descending). Before 9:00 the previous trading day's data is returned; during 9:00–9:14 an empty result is returned; from 9:15 today's data is available. Requires a `quote:*` scope.",
|
|
1428
|
+
summary: "List the A-share limit-up pool for a trade date.",
|
|
1625
1429
|
positional: [],
|
|
1626
1430
|
outputDefault: "json",
|
|
1627
1431
|
pagination: "none",
|
|
@@ -1655,7 +1459,7 @@ Phase 5.2 (server endpoint).
|
|
|
1655
1459
|
include_broken: {
|
|
1656
1460
|
type: "boolean",
|
|
1657
1461
|
default: false,
|
|
1658
|
-
description: "true
|
|
1462
|
+
description: "true 时连真炸板(盘中封板后跌出、当前未回封,status=broken)也一起返回;默认只返回当前封板 status=limit_up。"
|
|
1659
1463
|
}
|
|
1660
1464
|
},
|
|
1661
1465
|
additionalProperties: false
|
|
@@ -1666,8 +1470,8 @@ Phase 5.2 (server endpoint).
|
|
|
1666
1470
|
cliName: "limit-up summary",
|
|
1667
1471
|
method: "GET",
|
|
1668
1472
|
path: "/v1/limit-up/summary",
|
|
1669
|
-
description: "
|
|
1670
|
-
summary: "A-share limit-up
|
|
1473
|
+
description: "Returns aggregate limit-up statistics for the trade date: limit-up count, seal-break count, limit-down count, the highest consecutive-board height, and a height ladder (`ladder: [{ height, count }, ...]`). The height ladder counts only stocks currently sealed at limit-up. Pre-open fallback follows the same rules as the limit-up pool. Requires a `quote:*` scope.",
|
|
1474
|
+
summary: "Summarize A-share limit-up activity for a trade date.",
|
|
1671
1475
|
positional: [],
|
|
1672
1476
|
outputDefault: "json",
|
|
1673
1477
|
pagination: "none",
|
|
@@ -1707,8 +1511,8 @@ Phase 5.2 (server endpoint).
|
|
|
1707
1511
|
cliName: "market status",
|
|
1708
1512
|
method: "GET",
|
|
1709
1513
|
path: "/v1/market/status",
|
|
1710
|
-
description: "
|
|
1711
|
-
summary: "
|
|
1514
|
+
description: "Returns the current A-share trading session (pre-open / open / lunch / closed), the current and next trading day, and a holiday flag. Requires the `market:read` scope or any `quote:*` scope.",
|
|
1515
|
+
summary: "Get the current A-share market session state.",
|
|
1712
1516
|
positional: [],
|
|
1713
1517
|
outputDefault: "json",
|
|
1714
1518
|
pagination: "none",
|
|
@@ -1734,8 +1538,8 @@ Phase 5.2 (server endpoint).
|
|
|
1734
1538
|
cliName: "news feed",
|
|
1735
1539
|
method: "GET",
|
|
1736
1540
|
path: "/v1/news",
|
|
1737
|
-
description: "
|
|
1738
|
-
summary: "List recent news
|
|
1541
|
+
description: "Returns recent news. Equivalent to `/v1/news/list`; retained for backward compatibility. Partner/agent callers receive `fields=compact` by default (id, title, ai_summary, tagged securities, first ~300 chars of content); pass `fields=full` for complete content.",
|
|
1542
|
+
summary: "List recent news.",
|
|
1739
1543
|
positional: [],
|
|
1740
1544
|
outputDefault: "json",
|
|
1741
1545
|
pagination: "offset",
|
|
@@ -1747,7 +1551,16 @@ Phase 5.2 (server endpoint).
|
|
|
1747
1551
|
dryRunSupported: false,
|
|
1748
1552
|
inputSchema: {
|
|
1749
1553
|
type: "object",
|
|
1750
|
-
properties: {
|
|
1554
|
+
properties: {
|
|
1555
|
+
fields: {
|
|
1556
|
+
type: "string",
|
|
1557
|
+
enum: [
|
|
1558
|
+
"compact",
|
|
1559
|
+
"full"
|
|
1560
|
+
],
|
|
1561
|
+
description: "Response shape: `compact` (the default for partner/agent callers) returns id, title, ai_summary, tagged securities, and the first ~300 chars of content with a `content_truncated` flag; `full` returns complete content."
|
|
1562
|
+
}
|
|
1563
|
+
},
|
|
1751
1564
|
additionalProperties: false
|
|
1752
1565
|
}
|
|
1753
1566
|
},
|
|
@@ -1756,8 +1569,8 @@ Phase 5.2 (server endpoint).
|
|
|
1756
1569
|
cliName: "news get",
|
|
1757
1570
|
method: "GET",
|
|
1758
1571
|
path: "/v1/news/{news_id}",
|
|
1759
|
-
description: "
|
|
1760
|
-
summary: "
|
|
1572
|
+
description: "Returns the full content of one news item: title, content snippet, and tagged securities.",
|
|
1573
|
+
summary: "Get a single news item by id.",
|
|
1761
1574
|
positional: [
|
|
1762
1575
|
"news_id"
|
|
1763
1576
|
],
|
|
@@ -1788,8 +1601,8 @@ Phase 5.2 (server endpoint).
|
|
|
1788
1601
|
cliName: "news list",
|
|
1789
1602
|
method: "GET",
|
|
1790
1603
|
path: "/v1/news/list",
|
|
1791
|
-
description: "
|
|
1792
|
-
summary: "List news mentioning
|
|
1604
|
+
description: "Returns news items mentioning a specific A-share security, ordered by publication date descending. Requires the `news:read` scope.",
|
|
1605
|
+
summary: "List news mentioning one security.",
|
|
1793
1606
|
positional: [],
|
|
1794
1607
|
outputDefault: "json",
|
|
1795
1608
|
pagination: "none",
|
|
@@ -1839,6 +1652,14 @@ Phase 5.2 (server endpoint).
|
|
|
1839
1652
|
minimum: 0,
|
|
1840
1653
|
default: 0,
|
|
1841
1654
|
description: "Pagination offset (page through long history ranges)."
|
|
1655
|
+
},
|
|
1656
|
+
fields: {
|
|
1657
|
+
type: "string",
|
|
1658
|
+
enum: [
|
|
1659
|
+
"compact",
|
|
1660
|
+
"full"
|
|
1661
|
+
],
|
|
1662
|
+
description: "Response shape: `compact` (the default for partner/agent callers) returns id, title/ai_summary, attribution, tagged securities, and the first ~300 chars of content with a `content_truncated` flag; `full` returns complete content. Prefer compact for scanning; fetch full text per item only when needed."
|
|
1842
1663
|
}
|
|
1843
1664
|
},
|
|
1844
1665
|
additionalProperties: false,
|
|
@@ -1852,8 +1673,8 @@ Phase 5.2 (server endpoint).
|
|
|
1852
1673
|
cliName: "news search",
|
|
1853
1674
|
method: "GET",
|
|
1854
1675
|
path: "/v1/news/search",
|
|
1855
|
-
description: "Full-text search recent news
|
|
1856
|
-
summary: "Full-text search recent news",
|
|
1676
|
+
description: "Full-text search over recent news and market briefs. Returns title, publication date, snippet, and tagged securities. Requires the `news:read` scope. Note: news fields are user-generated; `meta.untrusted_text_fields` lists fields that should be sanitized before being passed to an LLM.",
|
|
1677
|
+
summary: "Full-text search recent news.",
|
|
1857
1678
|
positional: [],
|
|
1858
1679
|
outputDefault: "json",
|
|
1859
1680
|
pagination: "none",
|
|
@@ -1904,6 +1725,14 @@ Phase 5.2 (server endpoint).
|
|
|
1904
1725
|
minimum: 0,
|
|
1905
1726
|
default: 0,
|
|
1906
1727
|
description: "Pagination offset (page through long history ranges)."
|
|
1728
|
+
},
|
|
1729
|
+
fields: {
|
|
1730
|
+
type: "string",
|
|
1731
|
+
enum: [
|
|
1732
|
+
"compact",
|
|
1733
|
+
"full"
|
|
1734
|
+
],
|
|
1735
|
+
description: "Response shape: `compact` (the default for partner/agent callers) returns id, title/ai_summary, attribution, tagged securities, and the first ~300 chars of content with a `content_truncated` flag; `full` returns complete content. Prefer compact for scanning; fetch full text per item only when needed."
|
|
1907
1736
|
}
|
|
1908
1737
|
},
|
|
1909
1738
|
additionalProperties: false,
|
|
@@ -1917,10 +1746,8 @@ Phase 5.2 (server endpoint).
|
|
|
1917
1746
|
cliName: "ownership lockups",
|
|
1918
1747
|
method: "GET",
|
|
1919
1748
|
path: "/v1/ownership-events/lockups",
|
|
1920
|
-
description:
|
|
1921
|
-
|
|
1922
|
-
`,
|
|
1923
|
-
summary: "Scan upcoming share-lockup expirations across the whole market",
|
|
1749
|
+
description: "Scans the whole market for share lockups expiring within the next `days` days, sorted by unlock date ascending then by unlocking ratio descending — a forward-looking selling-pressure screen across all securities. Use `min_pct` to filter out small unlocks and `limit` to cap the result size. T+1 data.",
|
|
1750
|
+
summary: "Scan upcoming share-lockup expirations market-wide.",
|
|
1924
1751
|
positional: [],
|
|
1925
1752
|
outputDefault: "json",
|
|
1926
1753
|
pagination: "none",
|
|
@@ -1965,20 +1792,8 @@ digest 给不了(digest 是单 code 维度)。min_pct 过滤小额解禁,l
|
|
|
1965
1792
|
cliName: "ownership show",
|
|
1966
1793
|
method: "GET",
|
|
1967
1794
|
path: "/v1/ownership-events",
|
|
1968
|
-
description:
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
- shareholder_transactions:增减持回看 txn_days 天,含净增减股数/比例 +
|
|
1972
|
-
增减笔数 + 明细(方向/股东/均价/区间)。
|
|
1973
|
-
- share_repurchases:回购回看 repurchase_days 天,含在进行笔数 + 已执行
|
|
1974
|
-
累计金额/股数(仅计 in_progress/completed)+ 最新进度 + 明细。
|
|
1975
|
-
- lockup_expirations:解禁前瞻 lockup_days 天(unlock_date ∈ [today,
|
|
1976
|
-
today+N]),含合计解禁股数/占比 + 最近解禁日 + 明细。前瞻抛压预警。
|
|
1977
|
-
|
|
1978
|
-
枚举 slug(direction / holder_category / status / lockup_type)见
|
|
1979
|
-
docs/OWNERSHIP_EVENTS.md。
|
|
1980
|
-
`,
|
|
1981
|
-
summary: "Ownership events for one A-share (holder trades / repurchases / lockups)",
|
|
1795
|
+
description: "Returns a structured three-in-one view of ownership events for one A-share security (canonical code, e.g. `SSE:600519`): recent shareholder transactions, recent share repurchases, and upcoming lockup expirations. T+1 data. Shareholder transactions look back `txn_days` days and include net change in shares/ratio, transaction count, and per-transaction detail (direction, holder, average price, date range). Repurchases look back `repurchase_days` days and include in-progress count, cumulative executed amount/shares, latest progress, and detail. Lockup expirations look ahead `lockup_days` days and include total unlocking shares/ratio, the nearest unlock date, and detail — useful as a forward-looking selling-pressure warning. Enum values (direction, holder category, status, lockup type) are documented in the response schema.",
|
|
1796
|
+
summary: "Get ownership events for one security.",
|
|
1982
1797
|
positional: [],
|
|
1983
1798
|
outputDefault: "json",
|
|
1984
1799
|
pagination: "none",
|
|
@@ -2027,35 +1842,13 @@ docs/OWNERSHIP_EVENTS.md。
|
|
|
2027
1842
|
]
|
|
2028
1843
|
}
|
|
2029
1844
|
},
|
|
2030
|
-
"payment.plans": {
|
|
2031
|
-
cliKey: "payment.plans",
|
|
2032
|
-
cliName: "payment plans",
|
|
2033
|
-
method: "GET",
|
|
2034
|
-
path: "/v1/payment/plans",
|
|
2035
|
-
description: "返回订阅计划清单(plan_id + 价格 + 时长 + 描述)。",
|
|
2036
|
-
summary: "List subscription plans",
|
|
2037
|
-
positional: [],
|
|
2038
|
-
outputDefault: "json",
|
|
2039
|
-
pagination: "none",
|
|
2040
|
-
stream: false,
|
|
2041
|
-
billable: false,
|
|
2042
|
-
idempotencyRequired: false,
|
|
2043
|
-
scopesAny: [],
|
|
2044
|
-
sideEffect: "read",
|
|
2045
|
-
dryRunSupported: false,
|
|
2046
|
-
inputSchema: {
|
|
2047
|
-
type: "object",
|
|
2048
|
-
properties: {},
|
|
2049
|
-
additionalProperties: false
|
|
2050
|
-
}
|
|
2051
|
-
},
|
|
2052
1845
|
quote: {
|
|
2053
1846
|
cliKey: "quote",
|
|
2054
1847
|
cliName: "quote",
|
|
2055
1848
|
method: "GET",
|
|
2056
1849
|
path: "/v1/quote/realtime",
|
|
2057
|
-
description: "
|
|
2058
|
-
summary: "
|
|
1850
|
+
description: "Returns real-time quotes for one or more A-share securities (canonical codes, e.g. `SSE:600519`): last price, volume, percent change, and bid/ask. Up to 200 codes per call. The response carries a `session` label (`pre_open` / `auction` / `open` / `break` / `closed`) and, outside continuous trading, an explanatory `note`: during 9:00–9:14 pre-open the previous session's snapshot is returned; during the 9:15–9:29 call auction, prices are indicative auction match prices. Rows whose feed has stopped updating (suspension / feed drop) keep their last snapshot and are flagged `stale: true` with `stale_since`. Requires a `quote:l1`, `quote:l2`, or `quote:delayed` scope.",
|
|
1851
|
+
summary: "Get real-time quotes for one or more securities.",
|
|
2059
1852
|
positional: [],
|
|
2060
1853
|
outputDefault: "json",
|
|
2061
1854
|
pagination: "none",
|
|
@@ -2105,8 +1898,8 @@ docs/OWNERSHIP_EVENTS.md。
|
|
|
2105
1898
|
cliName: "quote scan",
|
|
2106
1899
|
method: "GET",
|
|
2107
1900
|
path: "/v1/quote/scan",
|
|
2108
|
-
description:
|
|
2109
|
-
summary: "
|
|
1901
|
+
description: "Returns a real-time quote for every A-share in a single call — use it for full-market scans or to discover a universe of interest when you do not yet know which codes to query. Filter with `exchange=SSE|SZSE|BSE` to narrow to one exchange. The payload is large (~3 MB, ~5,800 instruments), so pair it with `--fields`, `--jq`, or `--max-bytes` to trim it. The response carries a `session` label (`pre_open` / `auction` / `open` / `break` / `closed`) plus an explanatory `note` outside continuous trading: during 9:00–9:14 pre-open the previous session's snapshot is returned; during the 9:15–9:29 call auction, prices are indicative auction match prices. Instruments whose feed has stopped updating (suspension / feed drop) are excluded from the default scan; pass `include=all` to keep them, flagged with `stale: true` and `stale_since`. Each item also includes `main_net_in` (current-day cumulative net main-capital inflow in CNY, which may be negative) and a companion `main_net_in_stale` flag (true when served from the last-close fallback). Requires a `quote:l1`, `quote:l2`, or `quote:delayed` scope.",
|
|
1902
|
+
summary: "Snapshot every A-share real-time quote in one call.",
|
|
2110
1903
|
positional: [],
|
|
2111
1904
|
outputDefault: "json",
|
|
2112
1905
|
pagination: "none",
|
|
@@ -2134,6 +1927,15 @@ docs/OWNERSHIP_EVENTS.md。
|
|
|
2134
1927
|
"bse"
|
|
2135
1928
|
],
|
|
2136
1929
|
description: "Filter by exchange: SSE / SZSE / BSE (case-insensitive). Omit for all."
|
|
1930
|
+
},
|
|
1931
|
+
include: {
|
|
1932
|
+
type: "string",
|
|
1933
|
+
enum: [
|
|
1934
|
+
"active",
|
|
1935
|
+
"all"
|
|
1936
|
+
],
|
|
1937
|
+
default: "active",
|
|
1938
|
+
description: "`active` (default) excludes ST, delisted, and stale (feed-dropped / suspended) instruments; `all` returns the full set with stale rows flagged."
|
|
2137
1939
|
}
|
|
2138
1940
|
},
|
|
2139
1941
|
additionalProperties: false
|
|
@@ -2144,15 +1946,8 @@ docs/OWNERSHIP_EVENTS.md。
|
|
|
2144
1946
|
cliName: "search semantic",
|
|
2145
1947
|
method: "GET",
|
|
2146
1948
|
path: "/v1/search",
|
|
2147
|
-
description:
|
|
2148
|
-
|
|
2149
|
-
精排,叠时间衰减 + views 加权(views 主源优先)。
|
|
2150
|
-
|
|
2151
|
-
- 搜"锂电池"会带出新能源产业链(正极/负极/碳酸锂/宁德时代…)
|
|
2152
|
-
- 搜"芯片"会带出存储芯片/洁净室/晶圆代工…
|
|
2153
|
-
- mode=exact 兼容老 ILIKE 行为,仅在精确关键词命中时返回。
|
|
2154
|
-
`,
|
|
2155
|
-
summary: "Hybrid semantic search across news + analyst views",
|
|
1949
|
+
description: 'Hybrid semantic search across news and analyst views that generalizes beyond exact keywords. It combines exact entity matching (security codes, analysts), semantic (embedding-based) recall, and fuzzy matching, then fuses and re-ranks results with time decay and a weighting toward analyst views as the primary source. For example, searching "锂电池" surfaces the broader new-energy supply chain (cathode/anode materials, lithium carbonate, leading battery makers). Pass `mode=exact` for legacy exact-keyword behavior.',
|
|
1950
|
+
summary: "Semantic search across news and analyst views.",
|
|
2156
1951
|
positional: [],
|
|
2157
1952
|
outputDefault: "json",
|
|
2158
1953
|
pagination: "none",
|
|
@@ -2214,52 +2009,13 @@ docs/OWNERSHIP_EVENTS.md。
|
|
|
2214
2009
|
]
|
|
2215
2010
|
}
|
|
2216
2011
|
},
|
|
2217
|
-
"securities.industry": {
|
|
2218
|
-
cliKey: "securities.industry",
|
|
2219
|
-
cliName: "securities industry",
|
|
2220
|
-
method: "GET",
|
|
2221
|
-
path: "/v1/securities/industry",
|
|
2222
|
-
description: `返回该股票的 TDX 自定义行业代码(T1001 食品饮料等)与申万行业三级代码
|
|
2223
|
-
L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
2224
|
-
|
|
2225
|
-
用法:
|
|
2226
|
-
- 股票详情页"申万行业:白酒 / 食品饮料"标签
|
|
2227
|
-
- 筛选器交叉过滤:行业 + ROE/营收增长率
|
|
2228
|
-
- AI agent \`find_peers(code)\` 用申万二级行业找同业
|
|
2229
|
-
`,
|
|
2230
|
-
summary: "TDX + 申万 industry classification for one A-share security",
|
|
2231
|
-
positional: [],
|
|
2232
|
-
outputDefault: "json",
|
|
2233
|
-
pagination: "none",
|
|
2234
|
-
stream: false,
|
|
2235
|
-
billable: false,
|
|
2236
|
-
idempotencyRequired: false,
|
|
2237
|
-
scopesAny: [],
|
|
2238
|
-
sideEffect: "read",
|
|
2239
|
-
dryRunSupported: false,
|
|
2240
|
-
inputSchema: {
|
|
2241
|
-
type: "object",
|
|
2242
|
-
properties: {
|
|
2243
|
-
code: {
|
|
2244
|
-
type: "string",
|
|
2245
|
-
description: "A-share canonical code (SSE/SZSE/BSE only). For quote/chart/bars/financials endpoints.",
|
|
2246
|
-
pattern: "^(SSE|SZSE|BSE|SH|SZ|BJ):[0-9]{6}$",
|
|
2247
|
-
example: "SSE:600519"
|
|
2248
|
-
}
|
|
2249
|
-
},
|
|
2250
|
-
additionalProperties: false,
|
|
2251
|
-
required: [
|
|
2252
|
-
"code"
|
|
2253
|
-
]
|
|
2254
|
-
}
|
|
2255
|
-
},
|
|
2256
2012
|
"semantic.find": {
|
|
2257
2013
|
cliKey: "semantic.find",
|
|
2258
2014
|
cliName: "semantic find",
|
|
2259
2015
|
method: "GET",
|
|
2260
2016
|
path: "/v1/securities/search",
|
|
2261
|
-
description: "
|
|
2262
|
-
summary: "
|
|
2017
|
+
description: "Finds A-share securities matching a Chinese name, a code (e.g. `600519`), or pinyin initials (e.g. `gzmt`). Use it to turn a free-form description into canonical codes (e.g. `SSE:600519`).",
|
|
2018
|
+
summary: "Resolve A-share securities by name, code, or pinyin.",
|
|
2263
2019
|
positional: [],
|
|
2264
2020
|
outputDefault: "json",
|
|
2265
2021
|
pagination: "none",
|
|
@@ -2298,8 +2054,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2298
2054
|
cliName: "sentiment breadth",
|
|
2299
2055
|
method: "GET",
|
|
2300
2056
|
path: "/v1/sentiment/breadth",
|
|
2301
|
-
description: "
|
|
2302
|
-
summary: "
|
|
2057
|
+
description: "Returns the intraday market-breadth time series for one trading day. Omit `trade_date` for today (returns empty before 9:00); pass `YYYY-MM-DD` for any historical trading day (sparse minutes around the lunch break are excluded; up to 241 rows per day). Requires the `sentiment:read` scope.",
|
|
2058
|
+
summary: "Get the intraday market-breadth time series.",
|
|
2303
2059
|
positional: [],
|
|
2304
2060
|
outputDefault: "json",
|
|
2305
2061
|
pagination: "none",
|
|
@@ -2341,8 +2097,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2341
2097
|
cliName: "sentiment overview",
|
|
2342
2098
|
method: "GET",
|
|
2343
2099
|
path: "/v1/sentiment/overview",
|
|
2344
|
-
description: "
|
|
2345
|
-
summary: "
|
|
2100
|
+
description: "Returns an aggregate sentiment snapshot for the latest minute of one trading day: limit-up/down counts, breadth, divergence index, and moving-average / 52-week breadth. Omit `trade_date` for today's real-time snapshot (returns an empty structure before 9:00); pass `YYYY-MM-DD` for any historical day (the day's final aggregated minute). Requires the `sentiment:read` scope.",
|
|
2101
|
+
summary: "Get aggregate market sentiment indicators.",
|
|
2346
2102
|
positional: [],
|
|
2347
2103
|
outputDefault: "json",
|
|
2348
2104
|
pagination: "none",
|
|
@@ -2385,8 +2141,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2385
2141
|
cliName: "sentiment pct-distribution",
|
|
2386
2142
|
method: "GET",
|
|
2387
2143
|
path: "/v1/sentiment/pct-distribution",
|
|
2388
|
-
description: "
|
|
2389
|
-
summary: "
|
|
2144
|
+
description: "Returns the distribution of intraday percent change across the full A-share universe, bucketed (≤-10% / -9% / ... / +10% / limit-up), for visualizing market breadth.",
|
|
2145
|
+
summary: "Get the intraday percent-change distribution.",
|
|
2390
2146
|
positional: [],
|
|
2391
2147
|
outputDefault: "json",
|
|
2392
2148
|
pagination: "none",
|
|
@@ -2409,8 +2165,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2409
2165
|
cliName: "sentiment turnover",
|
|
2410
2166
|
method: "GET",
|
|
2411
2167
|
path: "/v1/sentiment/turnover",
|
|
2412
|
-
description: "
|
|
2413
|
-
summary: "
|
|
2168
|
+
description: "Returns the intraday turnover time series across one or more trading days. Omit `trade_date` for today (returns empty before 9:00); pass `YYYY-MM-DD` for that day plus the preceding `days-1` days. The response includes headline fields `current_turnover`, `predicted_total`, and `delta_vs_yesterday`. Requires the `sentiment:read` scope.",
|
|
2169
|
+
summary: "Get the intraday turnover time series.",
|
|
2414
2170
|
positional: [],
|
|
2415
2171
|
outputDefault: "json",
|
|
2416
2172
|
pagination: "none",
|
|
@@ -2459,8 +2215,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2459
2215
|
cliName: "stocks hot",
|
|
2460
2216
|
method: "GET",
|
|
2461
2217
|
path: "/v1/stocks/hot",
|
|
2462
|
-
description: "
|
|
2463
|
-
summary: "
|
|
2218
|
+
description: "Returns today's most-popular A-share stocks, ranked by a composite score of searches, follows, and comments.",
|
|
2219
|
+
summary: "Get today's hot-stock leaderboard.",
|
|
2464
2220
|
positional: [],
|
|
2465
2221
|
outputDefault: "json",
|
|
2466
2222
|
pagination: "none",
|
|
@@ -2481,8 +2237,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2481
2237
|
cliName: "stocks social-hot",
|
|
2482
2238
|
method: "GET",
|
|
2483
2239
|
path: "/v1/stocks/social-hot",
|
|
2484
|
-
description: "
|
|
2485
|
-
summary: "
|
|
2240
|
+
description: "Returns a leaderboard of A-share stocks aggregated by social-media mentions across multiple platforms, ranked by mention volume and sentiment score.",
|
|
2241
|
+
summary: "Get cross-platform social-hot stocks.",
|
|
2486
2242
|
positional: [],
|
|
2487
2243
|
outputDefault: "json",
|
|
2488
2244
|
pagination: "none",
|
|
@@ -2503,8 +2259,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2503
2259
|
cliName: "views document",
|
|
2504
2260
|
method: "GET",
|
|
2505
2261
|
path: "/v1/views/{view_id}/document",
|
|
2506
|
-
description: "
|
|
2507
|
-
summary: "
|
|
2262
|
+
description: "Returns the full parsed text of the research report behind one view. Available only for views with `full_text_available=true`. Large documents default to `format=outline`, returning a heading-only table of contents plus total character count; use `format=full` with `offset` / `max_chars` to page through the body via the `next_offset` cursor. Requires the `views:read` scope.",
|
|
2263
|
+
summary: "Get the full research-report text behind a view.",
|
|
2508
2264
|
positional: [
|
|
2509
2265
|
"view_id"
|
|
2510
2266
|
],
|
|
@@ -2559,8 +2315,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2559
2315
|
cliName: "views feed",
|
|
2560
2316
|
method: "GET",
|
|
2561
2317
|
path: "/v1/views",
|
|
2562
|
-
description: "
|
|
2563
|
-
summary: "List analyst views",
|
|
2318
|
+
description: "Returns a stream of analyst views, sell-side research, and long-form opinion. Filter by institution, analyst, security, or recency (`hours`). Partner/agent callers receive `fields=compact` by default (id, ai_summary, attribution, tagged securities, first ~300 chars of content); pass `fields=full` for complete content. Requires the `views:read` scope.",
|
|
2319
|
+
summary: "List analyst views.",
|
|
2564
2320
|
positional: [],
|
|
2565
2321
|
outputDefault: "json",
|
|
2566
2322
|
pagination: "offset",
|
|
@@ -2572,7 +2328,16 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2572
2328
|
dryRunSupported: false,
|
|
2573
2329
|
inputSchema: {
|
|
2574
2330
|
type: "object",
|
|
2575
|
-
properties: {
|
|
2331
|
+
properties: {
|
|
2332
|
+
fields: {
|
|
2333
|
+
type: "string",
|
|
2334
|
+
enum: [
|
|
2335
|
+
"compact",
|
|
2336
|
+
"full"
|
|
2337
|
+
],
|
|
2338
|
+
description: "Response shape: `compact` (the default for partner/agent callers) returns id, ai_summary, attribution, tagged securities, and the first ~300 chars of content with a `content_truncated` flag; `full` returns complete content."
|
|
2339
|
+
}
|
|
2340
|
+
},
|
|
2576
2341
|
additionalProperties: false
|
|
2577
2342
|
}
|
|
2578
2343
|
},
|
|
@@ -2581,8 +2346,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2581
2346
|
cliName: "views get",
|
|
2582
2347
|
method: "GET",
|
|
2583
2348
|
path: "/v1/views/{view_id}",
|
|
2584
|
-
description: "
|
|
2585
|
-
summary: "
|
|
2349
|
+
description: "Returns the full content of one analyst view: body, attached images, tagged securities, and AI summary.",
|
|
2350
|
+
summary: "Get a single analyst view.",
|
|
2586
2351
|
positional: [
|
|
2587
2352
|
"view_id"
|
|
2588
2353
|
],
|
|
@@ -2613,8 +2378,8 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2613
2378
|
cliName: "views recent",
|
|
2614
2379
|
method: "GET",
|
|
2615
2380
|
path: "/v1/views/recent",
|
|
2616
|
-
description: "
|
|
2617
|
-
summary: "
|
|
2381
|
+
description: "Returns recent broker / analyst views (research notes, price targets, ratings). Filter by analyst, institution, or a specific security. Requires the `views:read` scope.",
|
|
2382
|
+
summary: "List recent analyst views.",
|
|
2618
2383
|
positional: [],
|
|
2619
2384
|
outputDefault: "json",
|
|
2620
2385
|
pagination: "none",
|
|
@@ -2672,6 +2437,14 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
2672
2437
|
minimum: 0,
|
|
2673
2438
|
default: 0,
|
|
2674
2439
|
description: "Pagination offset (page through long history ranges)."
|
|
2440
|
+
},
|
|
2441
|
+
fields: {
|
|
2442
|
+
type: "string",
|
|
2443
|
+
enum: [
|
|
2444
|
+
"compact",
|
|
2445
|
+
"full"
|
|
2446
|
+
],
|
|
2447
|
+
description: "Response shape: `compact` (the default for partner/agent callers) returns id, title/ai_summary, attribution, tagged securities, and the first ~300 chars of content with a `content_truncated` flag; `full` returns complete content. Prefer compact for scanning; fetch full text per item only when needed."
|
|
2675
2448
|
}
|
|
2676
2449
|
},
|
|
2677
2450
|
additionalProperties: false
|
|
@@ -2728,7 +2501,7 @@ function attachOperation(cmd, op, dispatch) {
|
|
|
2728
2501
|
function buildCommandTree(program, dispatch) {
|
|
2729
2502
|
{
|
|
2730
2503
|
const noun = program.command("agent");
|
|
2731
|
-
noun.description("agent
|
|
2504
|
+
noun.description("Manage agent billing sessions and identity.");
|
|
2732
2505
|
{
|
|
2733
2506
|
const cmd = noun.command("session-end");
|
|
2734
2507
|
attachOperation(cmd, OPERATIONS["agent.session-end"], dispatch);
|
|
@@ -2744,7 +2517,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
2744
2517
|
}
|
|
2745
2518
|
{
|
|
2746
2519
|
const noun = program.command("announcements");
|
|
2747
|
-
noun.description("
|
|
2520
|
+
noun.description("Listed-company disclosures: feed, per-stock, and full-text search.");
|
|
2748
2521
|
{
|
|
2749
2522
|
const cmd = noun.command("detail");
|
|
2750
2523
|
attachOperation(cmd, OPERATIONS["announcements.detail"], dispatch);
|
|
@@ -2764,7 +2537,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
2764
2537
|
}
|
|
2765
2538
|
{
|
|
2766
2539
|
const noun = program.command("auth");
|
|
2767
|
-
noun.description("
|
|
2540
|
+
noun.description("Authentication and caller identity.");
|
|
2768
2541
|
{
|
|
2769
2542
|
const cmd = noun.command("whoami");
|
|
2770
2543
|
attachOperation(cmd, OPERATIONS["auth.whoami"], dispatch);
|
|
@@ -2772,7 +2545,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
2772
2545
|
}
|
|
2773
2546
|
{
|
|
2774
2547
|
const noun = program.command("bars");
|
|
2775
|
-
noun.description("bars
|
|
2548
|
+
noun.description("Historical OHLC price bars — daily and minute, single or batch.");
|
|
2776
2549
|
{
|
|
2777
2550
|
const cmd = noun.command("daily");
|
|
2778
2551
|
attachOperation(cmd, OPERATIONS["bars.daily"], dispatch);
|
|
@@ -2790,9 +2563,17 @@ function buildCommandTree(program, dispatch) {
|
|
|
2790
2563
|
attachOperation(cmd, OPERATIONS["bars.minute-batch"], dispatch);
|
|
2791
2564
|
}
|
|
2792
2565
|
}
|
|
2566
|
+
{
|
|
2567
|
+
const noun = program.command("capabilities");
|
|
2568
|
+
noun.description("capabilities commands");
|
|
2569
|
+
{
|
|
2570
|
+
const cmd = noun.command("show");
|
|
2571
|
+
attachOperation(cmd, OPERATIONS["capabilities.show"], dispatch);
|
|
2572
|
+
}
|
|
2573
|
+
}
|
|
2793
2574
|
{
|
|
2794
2575
|
const noun = program.command("concepts");
|
|
2795
|
-
noun.description("
|
|
2576
|
+
noun.description("Thematic concept boards: constituents, quotes, and alerts.");
|
|
2796
2577
|
{
|
|
2797
2578
|
const cmd = noun.command("alerts");
|
|
2798
2579
|
attachOperation(cmd, OPERATIONS["concepts.alerts"], dispatch);
|
|
@@ -2840,7 +2621,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
2840
2621
|
}
|
|
2841
2622
|
{
|
|
2842
2623
|
const noun = program.command("financials");
|
|
2843
|
-
noun.description("financials
|
|
2624
|
+
noun.description("Point-in-time fundamental financials.");
|
|
2844
2625
|
{
|
|
2845
2626
|
const cmd = noun.command("pit");
|
|
2846
2627
|
attachOperation(cmd, OPERATIONS["financials.pit"], dispatch);
|
|
@@ -2860,7 +2641,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
2860
2641
|
}
|
|
2861
2642
|
{
|
|
2862
2643
|
const noun = program.command("index");
|
|
2863
|
-
noun.description("
|
|
2644
|
+
noun.description("Index quotes and snapshots.");
|
|
2864
2645
|
{
|
|
2865
2646
|
const cmd = noun.command("daily-bars");
|
|
2866
2647
|
attachOperation(cmd, OPERATIONS["index.daily-bars"], dispatch);
|
|
@@ -2874,33 +2655,9 @@ function buildCommandTree(program, dispatch) {
|
|
|
2874
2655
|
attachOperation(cmd, OPERATIONS["index.snapshot"], dispatch);
|
|
2875
2656
|
}
|
|
2876
2657
|
}
|
|
2877
|
-
{
|
|
2878
|
-
const noun = program.command("industries");
|
|
2879
|
-
noun.description("industries commands");
|
|
2880
|
-
{
|
|
2881
|
-
const cmd = noun.command("alerts");
|
|
2882
|
-
attachOperation(cmd, OPERATIONS["industries.alerts"], dispatch);
|
|
2883
|
-
}
|
|
2884
|
-
{
|
|
2885
|
-
const cmd = noun.command("daily-bars");
|
|
2886
|
-
attachOperation(cmd, OPERATIONS["industries.daily-bars"], dispatch);
|
|
2887
|
-
}
|
|
2888
|
-
{
|
|
2889
|
-
const cmd = noun.command("list");
|
|
2890
|
-
attachOperation(cmd, OPERATIONS["industries.list"], dispatch);
|
|
2891
|
-
}
|
|
2892
|
-
{
|
|
2893
|
-
const cmd = noun.command("show");
|
|
2894
|
-
attachOperation(cmd, OPERATIONS["industries.show"], dispatch);
|
|
2895
|
-
}
|
|
2896
|
-
{
|
|
2897
|
-
const cmd = noun.command("snapshot");
|
|
2898
|
-
attachOperation(cmd, OPERATIONS["industries.snapshot"], dispatch);
|
|
2899
|
-
}
|
|
2900
|
-
}
|
|
2901
2658
|
{
|
|
2902
2659
|
const noun = program.command("limit-up");
|
|
2903
|
-
noun.description("limit-up
|
|
2660
|
+
noun.description("Daily limit-up pool and attribution analysis.");
|
|
2904
2661
|
{
|
|
2905
2662
|
const cmd = noun.command("analysis");
|
|
2906
2663
|
attachOperation(cmd, OPERATIONS["limit-up.analysis"], dispatch);
|
|
@@ -2920,7 +2677,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
2920
2677
|
}
|
|
2921
2678
|
{
|
|
2922
2679
|
const noun = program.command("market");
|
|
2923
|
-
noun.description("
|
|
2680
|
+
noun.description("Market-wide trading status and breadth.");
|
|
2924
2681
|
{
|
|
2925
2682
|
const cmd = noun.command("status");
|
|
2926
2683
|
attachOperation(cmd, OPERATIONS["market.status"], dispatch);
|
|
@@ -2928,7 +2685,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
2928
2685
|
}
|
|
2929
2686
|
{
|
|
2930
2687
|
const noun = program.command("news");
|
|
2931
|
-
noun.description("news
|
|
2688
|
+
noun.description("Market news feed and full-text search.");
|
|
2932
2689
|
{
|
|
2933
2690
|
const cmd = noun.command("feed");
|
|
2934
2691
|
attachOperation(cmd, OPERATIONS["news.feed"], dispatch);
|
|
@@ -2948,7 +2705,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
2948
2705
|
}
|
|
2949
2706
|
{
|
|
2950
2707
|
const noun = program.command("ownership");
|
|
2951
|
-
noun.description("
|
|
2708
|
+
noun.description("Insider trades, share buybacks, and lockup expirations.");
|
|
2952
2709
|
{
|
|
2953
2710
|
const cmd = noun.command("lockups");
|
|
2954
2711
|
attachOperation(cmd, OPERATIONS["ownership.lockups"], dispatch);
|
|
@@ -2958,14 +2715,6 @@ function buildCommandTree(program, dispatch) {
|
|
|
2958
2715
|
attachOperation(cmd, OPERATIONS["ownership.show"], dispatch);
|
|
2959
2716
|
}
|
|
2960
2717
|
}
|
|
2961
|
-
{
|
|
2962
|
-
const noun = program.command("payment");
|
|
2963
|
-
noun.description("payment commands");
|
|
2964
|
-
{
|
|
2965
|
-
const cmd = noun.command("plans");
|
|
2966
|
-
attachOperation(cmd, OPERATIONS["payment.plans"], dispatch);
|
|
2967
|
-
}
|
|
2968
|
-
}
|
|
2969
2718
|
{
|
|
2970
2719
|
const noun = program.command("quote");
|
|
2971
2720
|
noun.description("quote commands");
|
|
@@ -2980,23 +2729,15 @@ function buildCommandTree(program, dispatch) {
|
|
|
2980
2729
|
}
|
|
2981
2730
|
{
|
|
2982
2731
|
const noun = program.command("search");
|
|
2983
|
-
noun.description("
|
|
2732
|
+
noun.description("Search securities and content.");
|
|
2984
2733
|
{
|
|
2985
2734
|
const cmd = noun.command("semantic");
|
|
2986
2735
|
attachOperation(cmd, OPERATIONS["search.semantic"], dispatch);
|
|
2987
2736
|
}
|
|
2988
2737
|
}
|
|
2989
|
-
{
|
|
2990
|
-
const noun = program.command("securities");
|
|
2991
|
-
noun.description("securities commands");
|
|
2992
|
-
{
|
|
2993
|
-
const cmd = noun.command("industry");
|
|
2994
|
-
attachOperation(cmd, OPERATIONS["securities.industry"], dispatch);
|
|
2995
|
-
}
|
|
2996
|
-
}
|
|
2997
2738
|
{
|
|
2998
2739
|
const noun = program.command("semantic");
|
|
2999
|
-
noun.description("semantic
|
|
2740
|
+
noun.description("Meaning-based (semantic) security and content search.");
|
|
3000
2741
|
{
|
|
3001
2742
|
const cmd = noun.command("find");
|
|
3002
2743
|
attachOperation(cmd, OPERATIONS["semantic.find"], dispatch);
|
|
@@ -3004,7 +2745,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
3004
2745
|
}
|
|
3005
2746
|
{
|
|
3006
2747
|
const noun = program.command("sentiment");
|
|
3007
|
-
noun.description("sentiment
|
|
2748
|
+
noun.description("Market sentiment and breadth indicators.");
|
|
3008
2749
|
{
|
|
3009
2750
|
const cmd = noun.command("breadth");
|
|
3010
2751
|
attachOperation(cmd, OPERATIONS["sentiment.breadth"], dispatch);
|
|
@@ -3024,7 +2765,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
3024
2765
|
}
|
|
3025
2766
|
{
|
|
3026
2767
|
const noun = program.command("stocks");
|
|
3027
|
-
noun.description("
|
|
2768
|
+
noun.description("Per-stock overview, hot lists, and screening.");
|
|
3028
2769
|
{
|
|
3029
2770
|
const cmd = noun.command("hot");
|
|
3030
2771
|
attachOperation(cmd, OPERATIONS["stocks.hot"], dispatch);
|
|
@@ -3036,7 +2777,7 @@ function buildCommandTree(program, dispatch) {
|
|
|
3036
2777
|
}
|
|
3037
2778
|
{
|
|
3038
2779
|
const noun = program.command("views");
|
|
3039
|
-
noun.description("views
|
|
2780
|
+
noun.description("Analyst and broker research views (primary research source).");
|
|
3040
2781
|
{
|
|
3041
2782
|
const cmd = noun.command("document");
|
|
3042
2783
|
attachOperation(cmd, OPERATIONS["views.document"], dispatch);
|
|
@@ -3959,7 +3700,7 @@ import os2 from "node:os";
|
|
|
3959
3700
|
import path2 from "node:path";
|
|
3960
3701
|
|
|
3961
3702
|
// src/version.ts
|
|
3962
|
-
var CLI_VERSION = "2.
|
|
3703
|
+
var CLI_VERSION = "2.8.0";
|
|
3963
3704
|
|
|
3964
3705
|
// src/runtime/update_check.ts
|
|
3965
3706
|
var UPDATE_CACHE_PATH = path2.join(os2.homedir(), ".config", "echopai", "update_cache.json");
|
|
@@ -4092,9 +3833,10 @@ async function invoke(op, args, ctx) {
|
|
|
4092
3833
|
}
|
|
4093
3834
|
throw e;
|
|
4094
3835
|
}
|
|
3836
|
+
const opOwnedFlags = new Set(Object.keys(op.inputSchema.properties).filter((k) => SYSTEM_FLAGS.has(k)));
|
|
4095
3837
|
const apiParams = {};
|
|
4096
3838
|
for (const [k, v] of Object.entries(args)) {
|
|
4097
|
-
if (SYSTEM_FLAGS.has(k))
|
|
3839
|
+
if (SYSTEM_FLAGS.has(k) && !opOwnedFlags.has(k))
|
|
4098
3840
|
continue;
|
|
4099
3841
|
if (v === undefined || v === "")
|
|
4100
3842
|
continue;
|
|
@@ -4261,9 +4003,10 @@ async function invoke(op, args, ctx) {
|
|
|
4261
4003
|
let envelope = rawEnvelope;
|
|
4262
4004
|
try {
|
|
4263
4005
|
const jq = typeof args.jq === "string" ? args.jq : undefined;
|
|
4006
|
+
const fieldsProjection = opOwnedFlags.has("fields") ? undefined : parseFieldsFlag(args.fields);
|
|
4264
4007
|
envelope = applyFilters(rawEnvelope, {
|
|
4265
4008
|
...jq ? { query: jq } : {},
|
|
4266
|
-
...
|
|
4009
|
+
...fieldsProjection ? { fields: fieldsProjection } : {},
|
|
4267
4010
|
...parseMaxBytesFlag(args.max_bytes) ? { maxBytes: parseMaxBytesFlag(args.max_bytes) } : {}
|
|
4268
4011
|
});
|
|
4269
4012
|
} catch (e) {
|
|
@@ -4873,6 +4616,19 @@ function buildBarsBatchCommand() {
|
|
|
4873
4616
|
});
|
|
4874
4617
|
return cmd;
|
|
4875
4618
|
}
|
|
4619
|
+
// src/verbs/capabilities.ts
|
|
4620
|
+
var capabilitiesSpec = {
|
|
4621
|
+
name: "capabilities",
|
|
4622
|
+
description: "API capability changelog and spec-version discovery. Returns the current spec version plus a newest-first changelog of capability changes (new endpoints, new fields, behavior fixes). Call once at session start — or when a response shape surprises you — to learn what changed since your integration was written. Free, unauthenticated, non-billable.",
|
|
4623
|
+
inputSchema: {},
|
|
4624
|
+
handler: async (_args, ctx) => {
|
|
4625
|
+
const op = OPERATIONS["capabilities.show"];
|
|
4626
|
+
if (!op)
|
|
4627
|
+
throw new Error("capabilities.show op missing from codegen");
|
|
4628
|
+
return callOp(op, {}, ctx);
|
|
4629
|
+
},
|
|
4630
|
+
backingOps: ["capabilities.show"]
|
|
4631
|
+
};
|
|
4876
4632
|
// src/verbs/chart.ts
|
|
4877
4633
|
import { Command as Command5, Option as Option4 } from "commander";
|
|
4878
4634
|
import { z as z3 } from "zod";
|
|
@@ -5818,9 +5574,29 @@ function buildHotCommand() {
|
|
|
5818
5574
|
});
|
|
5819
5575
|
return cmd;
|
|
5820
5576
|
}
|
|
5577
|
+
// src/verbs/indices.ts
|
|
5578
|
+
import { z as z8 } from "zod";
|
|
5579
|
+
var indexSnapshotSpec = {
|
|
5580
|
+
name: "index_snapshot",
|
|
5581
|
+
description: "Real-time snapshot for the 172 A-share indices with a live quote feed (e.g. 上证指数 SSE:000001, 深证成指 SZSE:399001, 创业板指 SZSE:399006, 科创50 SSE:000688, 北证50 BSE:899050): price, pct_change, amount, speed_3min per index, refreshed ~15s during market hours (last intraday snapshot outside trading hours). Pass `codes` to narrow to a subset; omit for all 172. Use this for 'how is the broad market doing right now' — `quote` covers individual stocks only. CSI-series indices (CSI:*) have no live feed and are not returned.",
|
|
5582
|
+
inputSchema: {
|
|
5583
|
+
codes: z8.array(z8.string().regex(/^(SSE|SZSE|BSE):[0-9]{6}$/)).min(1).max(172).optional().describe("Canonical index codes to narrow the snapshot (e.g. ['SSE:000001', 'BSE:899050']); omit for all 172")
|
|
5584
|
+
},
|
|
5585
|
+
handler: async (args, ctx) => {
|
|
5586
|
+
const op = OPERATIONS["index.snapshot"];
|
|
5587
|
+
if (!op)
|
|
5588
|
+
throw new Error("index.snapshot op missing from codegen");
|
|
5589
|
+
const callArgs = {};
|
|
5590
|
+
if (Array.isArray(args.codes) && args.codes.length > 0) {
|
|
5591
|
+
callArgs.codes = args.codes.join(",");
|
|
5592
|
+
}
|
|
5593
|
+
return callOp(op, callArgs, ctx);
|
|
5594
|
+
},
|
|
5595
|
+
backingOps: ["index.snapshot"]
|
|
5596
|
+
};
|
|
5821
5597
|
// src/verbs/limit_up.ts
|
|
5822
5598
|
import { Command as Command11, Option as Option9 } from "commander";
|
|
5823
|
-
import { z as
|
|
5599
|
+
import { z as z9 } from "zod";
|
|
5824
5600
|
var DATE_RE5 = /^\d{4}-\d{2}-\d{2}$/;
|
|
5825
5601
|
var INCLUDE_VALUES = ["active", "all"];
|
|
5826
5602
|
function clampInt5(raw, min, max, fallback) {
|
|
@@ -5837,9 +5613,9 @@ var limitUpPoolSpec = {
|
|
|
5837
5613
|
name: "limit_up_pool",
|
|
5838
5614
|
description: "A-share limit-up pool for a given trade date — per-stock detail: first/last seal time, final pct, seal amount/volume, broken count, consecutive_days (连板数), board_count_within (N-day 板数), one-word-board flag, current status (limit_up / broken), board classification. Sort: consecutive_days desc → board_count_within desc → seal_amount desc. Pre-open fallback applies. Use when an agent needs the concrete list of '今天涨停了哪些票'.",
|
|
5839
5615
|
inputSchema: {
|
|
5840
|
-
trade_date:
|
|
5841
|
-
include:
|
|
5842
|
-
include_broken:
|
|
5616
|
+
trade_date: z9.string().regex(DATE_RE5).optional().describe("ISO date YYYY-MM-DD; omit for latest (pre-open fallback)"),
|
|
5617
|
+
include: z9.enum(INCLUDE_VALUES).default("active").describe("active = 排除 ST/退市(默认); all = 全部"),
|
|
5618
|
+
include_broken: z9.boolean().default(false).describe("true 时连炸板(status=broken)也一起返回;默认只返回当前封板 status=limit_up")
|
|
5843
5619
|
},
|
|
5844
5620
|
handler: async (args, ctx) => {
|
|
5845
5621
|
const op = OPERATIONS["limit-up.pool"];
|
|
@@ -5859,8 +5635,8 @@ var limitUpSummarySpec = {
|
|
|
5859
5635
|
name: "limit_up_summary",
|
|
5860
5636
|
description: "Limit-up summary for a given trade date: 涨停数 (limit_up_count) / 炸板数 (broken_count) / 跌停数 (limit_down_count) / 最高连板 (max_height) / 连板梯队 ladder[{height, count}]. 炸板/跌停 与情绪页同源 (market_breadth_intraday 当日最新分钟行). Pre-open fallback applies.",
|
|
5861
5637
|
inputSchema: {
|
|
5862
|
-
trade_date:
|
|
5863
|
-
include:
|
|
5638
|
+
trade_date: z9.string().regex(DATE_RE5).optional().describe("ISO date YYYY-MM-DD; omit for latest"),
|
|
5639
|
+
include: z9.enum(INCLUDE_VALUES).default("active").describe("active = all_a_ex_st 口径(默认); all = all_a 口径")
|
|
5864
5640
|
},
|
|
5865
5641
|
handler: async (args, ctx) => {
|
|
5866
5642
|
const op = OPERATIONS["limit-up.summary"];
|
|
@@ -5877,7 +5653,7 @@ var limitUpHistorySpec = {
|
|
|
5877
5653
|
name: "limit_up_history",
|
|
5878
5654
|
description: "Daily limit-up trend over the last N trading days: { trade_date, limit_up_count, broken_count, max_height }. 涨停数/最高连板 from market_limit_up_pool; 炸板数 from market_breadth_intraday (all_a_ex_st). Sorted by trade_date asc (oldest first).",
|
|
5879
5655
|
inputSchema: {
|
|
5880
|
-
days:
|
|
5656
|
+
days: z9.number().int().min(1).max(250).default(30).describe("Lookback window in trading days (1-250, default 30)")
|
|
5881
5657
|
},
|
|
5882
5658
|
handler: async (args, ctx) => {
|
|
5883
5659
|
const op = OPERATIONS["limit-up.history"];
|
|
@@ -5891,7 +5667,7 @@ var limitUpAnalysisSpec = {
|
|
|
5891
5667
|
name: "limit_up_analysis",
|
|
5892
5668
|
description: "Per-stock limit-up LLM attribution for a given trade date: leading_concept (主导题材) + concept_tags (相关标签) + reason (涨停理由). Themes are judged by an LLM from the latest research / views / news (NOT from the concept graph, so brand-new themes are covered) and refreshed across 6 Beijing slots daily. Complements limit-up pool (which says '哪些票涨停'); this says '为什么涨停/属什么题材'. STALE-DATA WARNING: omitting trade_date returns the latest *attributed* trading day, NOT necessarily today — before today's first slot lands (~09:47 Beijing) it falls back to the PREVIOUS day's attribution. For today's data pass trade_date explicitly and verify the returned trade_date / generated_at fields. An explicit trade_date with no attribution yet returns an empty analyses list.",
|
|
5893
5669
|
inputSchema: {
|
|
5894
|
-
trade_date:
|
|
5670
|
+
trade_date: z9.string().regex(DATE_RE5).optional().describe("ISO date YYYY-MM-DD; omit for the latest *attributed* day (falls back to the previous day until today's first slot lands ~09:47 Beijing — pass today explicitly for today's data)")
|
|
5895
5671
|
},
|
|
5896
5672
|
handler: async (args, ctx) => {
|
|
5897
5673
|
const op = OPERATIONS["limit-up.analysis"];
|
|
@@ -5957,7 +5733,7 @@ function buildLimitUpCommand() {
|
|
|
5957
5733
|
}
|
|
5958
5734
|
// src/verbs/lookup.ts
|
|
5959
5735
|
import { Command as Command12, Option as Option10 } from "commander";
|
|
5960
|
-
import { z as
|
|
5736
|
+
import { z as z10 } from "zod";
|
|
5961
5737
|
function mapLookupResponse(raw) {
|
|
5962
5738
|
if (!Array.isArray(raw))
|
|
5963
5739
|
return [];
|
|
@@ -5981,8 +5757,8 @@ var lookupSpec = {
|
|
|
5981
5757
|
name: "lookup",
|
|
5982
5758
|
description: "Resolve a Chinese name / A-share code / pinyin initials to canonical codes (e.g. SSE:600519). Use this first whenever the agent has a description but needs a canonical_code for downstream calls. AH dual-listing: when a company is listed on both A-share and HK (e.g. 工商银行 SSE:601398 / HK:01398), prefer the A-share canonical for all downstream analysis unless the user explicitly asks for the HK side.",
|
|
5983
5759
|
inputSchema: {
|
|
5984
|
-
text:
|
|
5985
|
-
limit:
|
|
5760
|
+
text: z10.string().min(1).max(50).describe("Search text: Chinese name (贵州茅台), code (600519), or pinyin (gzmt)"),
|
|
5761
|
+
limit: z10.number().int().min(1).max(30).default(10).describe("Max matches (1-30)")
|
|
5986
5762
|
},
|
|
5987
5763
|
handler: async (args, ctx) => {
|
|
5988
5764
|
const op = OPERATIONS["semantic.find"];
|
|
@@ -6016,7 +5792,7 @@ function buildLookupCommand() {
|
|
|
6016
5792
|
}
|
|
6017
5793
|
// src/verbs/market.ts
|
|
6018
5794
|
import { Command as Command13, Option as Option11 } from "commander";
|
|
6019
|
-
import { z as
|
|
5795
|
+
import { z as z11 } from "zod";
|
|
6020
5796
|
var marketStatusSpec = {
|
|
6021
5797
|
name: "market_status",
|
|
6022
5798
|
description: "Current A-share market session: pre-open / open / lunch / closed; current and next trading day; holiday flag. Cheap and non-billable — call it before any quote / bars fetch when the agent needs to decide pre-market fallback vs intraday vs after-close behavior.",
|
|
@@ -6069,10 +5845,10 @@ var marketMoversSpec = {
|
|
|
6069
5845
|
name: "market_movers",
|
|
6070
5846
|
description: "A-share market movers — top N from the full real-time snapshot, sorted by chosen field. Sort keys: `pct` (涨幅榜) / `pct_asc` (跌幅榜) / `speed` (3-min 涨速 speed_3min) / `amount` (成交额) / `turnover` (换手率 turnover_rate) / `total_mv` (总市值). Backed by `quote.scan` so 9:00-9:14 集合竞价时段会返空 (with `note`). Defaults: sort=pct, top=20, include=active (排除 ST / 退市). Use this for /market-style 'who's running today' instead of pulling the full 3 MB scan and sorting client-side.",
|
|
6071
5847
|
inputSchema: {
|
|
6072
|
-
sort:
|
|
6073
|
-
top:
|
|
6074
|
-
exchange:
|
|
6075
|
-
include:
|
|
5848
|
+
sort: z11.enum(MOVERS_SORT_VALUES).default("pct").describe("Sort field: pct / pct_asc / speed / amount / turnover / total_mv"),
|
|
5849
|
+
top: z11.number().int().min(1).max(500).default(20).describe("Top N items (1-500, default 20)"),
|
|
5850
|
+
exchange: z11.enum(EXCHANGE_VALUES).optional().describe("Narrow to one exchange: SSE / SZSE / BSE"),
|
|
5851
|
+
include: z11.enum(INCLUDE_VALUES2).default("active").describe("active = 排除 ST/退市(默认); all = 全集(含 ST + 退市 + 未知 status)")
|
|
6076
5852
|
},
|
|
6077
5853
|
handler: async (args, ctx) => {
|
|
6078
5854
|
const op = OPERATIONS["quote.scan"];
|
|
@@ -6156,18 +5932,19 @@ function buildMarketCommand() {
|
|
|
6156
5932
|
}
|
|
6157
5933
|
// src/verbs/news.ts
|
|
6158
5934
|
import { Command as Command14, Option as Option12 } from "commander";
|
|
6159
|
-
import { z as
|
|
5935
|
+
import { z as z12 } from "zod";
|
|
6160
5936
|
var newsSpec = {
|
|
6161
5937
|
name: "news",
|
|
6162
|
-
description: "SUPPLEMENTARY news / market briefs (short time-horizon event stream). Use ONLY to fill gaps not covered by `views`; prefer `views` as the primary research source. Three modes: `code` (canonical, works across A-share | HK | US — e.g. SSE:600519, HK:00700 腾讯, US:BABA) → news mentioning that security; `query` (free text) → full-text search; neither → recent time-window feed. AH dual-listing: when filtering by `code` for an A+H listed company, pass the A-share canonical (e.g. SSE:601398) for consolidated coverage; HK side only if the user explicitly asks. Note: `query` is matched against news text, so passing a canonical_code as `query` will not work — use `code` for security filtering.",
|
|
5938
|
+
description: "SUPPLEMENTARY news / market briefs (short time-horizon event stream). Use ONLY to fill gaps not covered by `views`; prefer `views` as the primary research source. Returns `fields=compact` by default (title + ai_summary + first ~300 chars of content, `content_truncated` flag) — typically 20-50x smaller than full; pass fields='full' only when you need complete article text. Three modes: `code` (canonical, works across A-share | HK | US — e.g. SSE:600519, HK:00700 腾讯, US:BABA) → news mentioning that security; `query` (free text) → full-text search; neither → recent time-window feed. AH dual-listing: when filtering by `code` for an A+H listed company, pass the A-share canonical (e.g. SSE:601398) for consolidated coverage; HK side only if the user explicitly asks. Note: `query` is matched against news text, so passing a canonical_code as `query` will not work — use `code` for security filtering.",
|
|
6163
5939
|
inputSchema: {
|
|
6164
|
-
code:
|
|
6165
|
-
query:
|
|
6166
|
-
hours:
|
|
6167
|
-
from:
|
|
6168
|
-
to:
|
|
6169
|
-
offset:
|
|
6170
|
-
limit:
|
|
5940
|
+
code: z12.string().regex(/^((SSE|SZSE|BSE):[0-9]{6}|HK:[0-9]{5}|US:[A-Z][A-Z0-9.\-]{0,5})$/).optional().describe("Filter by security canonical_code (e.g. SSE:600519, HK:00700). Takes precedence over `query`."),
|
|
5941
|
+
query: z12.string().optional().describe("Free-text query (Chinese or English) matched against news content; omit for time-window feed. Do NOT pass canonical_code here — use `code` instead."),
|
|
5942
|
+
hours: z12.number().int().min(1).max(168).default(24).describe("Rolling-feed lookback in hours (default 24 — much narrower than views). For longer history use from/to with code or query."),
|
|
5943
|
+
from: z12.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("History range start (China date YYYY-MM-DD). Range mode: needs code or query; Pro-only up to 365 days back."),
|
|
5944
|
+
to: z12.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("History range end (inclusive, China date; defaults to today). Use with from."),
|
|
5945
|
+
offset: z12.number().int().min(0).optional().describe("Pagination offset for paging through long history ranges."),
|
|
5946
|
+
limit: z12.number().int().min(1).max(100).default(20).describe("Max items per page"),
|
|
5947
|
+
fields: z12.enum(["compact", "full"]).optional().describe("Response shape: compact (default — title + ai_summary + first ~300 chars) or full (complete content)")
|
|
6171
5948
|
},
|
|
6172
5949
|
handler: async (args, ctx) => {
|
|
6173
5950
|
const { opKey, callArgs } = buildNewsCall(args);
|
|
@@ -6180,11 +5957,14 @@ var newsSpec = {
|
|
|
6180
5957
|
};
|
|
6181
5958
|
function buildNewsCall(args) {
|
|
6182
5959
|
const hasRange = typeof args.from === "string" && args.from.length > 0;
|
|
5960
|
+
const fields = args.fields === "compact" || args.fields === "full" ? args.fields : undefined;
|
|
6183
5961
|
const withWindow = (a) => {
|
|
6184
5962
|
if (typeof args.limit === "number")
|
|
6185
5963
|
a.limit = args.limit;
|
|
6186
5964
|
if (typeof args.offset === "number")
|
|
6187
5965
|
a.offset = args.offset;
|
|
5966
|
+
if (fields)
|
|
5967
|
+
a.fields = fields;
|
|
6188
5968
|
if (hasRange) {
|
|
6189
5969
|
a.from = args.from;
|
|
6190
5970
|
if (typeof args.to === "string" && args.to.length > 0)
|
|
@@ -6201,7 +5981,7 @@ function buildNewsCall(args) {
|
|
|
6201
5981
|
if (hasRange) {
|
|
6202
5982
|
throw new Error("range history (from/to) requires --code or --query; the bare feed has no narrowing filter");
|
|
6203
5983
|
}
|
|
6204
|
-
return { opKey: "news.feed", callArgs: {} };
|
|
5984
|
+
return { opKey: "news.feed", callArgs: fields ? { fields } : {} };
|
|
6205
5985
|
}
|
|
6206
5986
|
function clamp3(raw, min, max, fallback) {
|
|
6207
5987
|
const n = Math.floor(Number(raw));
|
|
@@ -6222,6 +6002,10 @@ function buildNewsCommand() {
|
|
|
6222
6002
|
cmd.addOption(new Option12("--to <date>", "History range end YYYY-MM-DD (inclusive; default today)"));
|
|
6223
6003
|
cmd.addOption(new Option12("--offset <n>", "Pagination offset for long history").default("0"));
|
|
6224
6004
|
cmd.addOption(new Option12("--limit <n>", "Max items").default("20"));
|
|
6005
|
+
cmd.addOption(new Option12("--fields <mode>", "Response shape: compact (default) or full").choices([
|
|
6006
|
+
"compact",
|
|
6007
|
+
"full"
|
|
6008
|
+
]));
|
|
6225
6009
|
cmd.action(async (opts) => {
|
|
6226
6010
|
const args = {
|
|
6227
6011
|
hours: clamp3(opts.hours, 1, 168, 24),
|
|
@@ -6236,19 +6020,21 @@ function buildNewsCommand() {
|
|
|
6236
6020
|
args.from = opts.from;
|
|
6237
6021
|
if (opts.to)
|
|
6238
6022
|
args.to = opts.to;
|
|
6023
|
+
if (opts.fields)
|
|
6024
|
+
args.fields = opts.fields;
|
|
6239
6025
|
await executeVerb(async (ctx) => newsSpec.handler(args, ctx));
|
|
6240
6026
|
});
|
|
6241
6027
|
return cmd;
|
|
6242
6028
|
}
|
|
6243
6029
|
// src/verbs/quote.ts
|
|
6244
6030
|
import { Command as Command15, Option as Option13 } from "commander";
|
|
6245
|
-
import { z as
|
|
6031
|
+
import { z as z13 } from "zod";
|
|
6246
6032
|
var quoteSpec = {
|
|
6247
6033
|
name: "quote",
|
|
6248
6034
|
description: "Real-time quote for 1-200 A-share securities (last price, volume, change %, bid/ask). For >200 codes use `scan` instead. AH dual-listing: HK codes are not supported here; for an A+H listed company use the A-share canonical (e.g. SSE:601398 not HK:01398).",
|
|
6249
6035
|
inputSchema: {
|
|
6250
|
-
codes:
|
|
6251
|
-
include_l2:
|
|
6036
|
+
codes: z13.array(z13.string().regex(/^(SSE|SZSE|BSE|SH|SZ|BJ):[0-9]{6}$/)).min(1).max(200).describe("Array of canonical codes (e.g. ['SSE:600519', 'SZSE:000001'])"),
|
|
6037
|
+
include_l2: z13.boolean().optional().describe("Include L2 5-level order book (requires quote:l2 scope)")
|
|
6252
6038
|
},
|
|
6253
6039
|
handler: async (args, ctx) => {
|
|
6254
6040
|
const op = OPERATIONS["quote"];
|
|
@@ -6279,12 +6065,12 @@ function buildQuoteCommand() {
|
|
|
6279
6065
|
}
|
|
6280
6066
|
// src/verbs/scan.ts
|
|
6281
6067
|
import { Command as Command16, Option as Option14 } from "commander";
|
|
6282
|
-
import { z as
|
|
6068
|
+
import { z as z14 } from "zod";
|
|
6283
6069
|
var scanSpec = {
|
|
6284
6070
|
name: "scan",
|
|
6285
6071
|
description: "Full-market real-time quote scan (~5800 A-share securities in one round-trip). Use for universe discovery; agents should slim output with field/byte limits in their tool host or post-processing.",
|
|
6286
6072
|
inputSchema: {
|
|
6287
|
-
exchange:
|
|
6073
|
+
exchange: z14.enum(["SSE", "SZSE", "BSE"]).optional().describe("Filter by exchange (omit for all)")
|
|
6288
6074
|
},
|
|
6289
6075
|
handler: async (args, ctx) => {
|
|
6290
6076
|
const op = OPERATIONS["quote.scan"];
|
|
@@ -6313,16 +6099,16 @@ function buildScanCommand() {
|
|
|
6313
6099
|
}
|
|
6314
6100
|
// src/verbs/search.ts
|
|
6315
6101
|
import { Command as Command17, Option as Option15 } from "commander";
|
|
6316
|
-
import { z as
|
|
6102
|
+
import { z as z15 } from "zod";
|
|
6317
6103
|
var searchSpec = {
|
|
6318
6104
|
name: "search",
|
|
6319
6105
|
description: "Structured-first hybrid search across analyst views + news (views weighted higher per feedback_views_over_news). Three lanes — entity (company codes / names, analyst names), concept-graph hub (theme alias → concept → constituents & research), and ParadeDB BM25 full-text (jieba) — fused with RRF. Deterministic & explainable: no vector kNN, no LLM rerank. Best for theme/concept queries: 'CPO' brings out 光模块/光通信/光芯片; '减肥药' brings out 创新药; '智驾' brings out 智能驾驶. Use `news` or `views` instead if you need strict time-window listing.",
|
|
6320
6106
|
inputSchema: {
|
|
6321
|
-
q:
|
|
6322
|
-
type:
|
|
6323
|
-
mode:
|
|
6324
|
-
hours:
|
|
6325
|
-
limit:
|
|
6107
|
+
q: z15.string().min(1).max(200).describe("Free-text query (Chinese or English)"),
|
|
6108
|
+
type: z15.enum(["news", "views", "all"]).default("all").describe("Search scope (views weighted higher in 'all')"),
|
|
6109
|
+
mode: z15.enum(["hybrid", "exact"]).default("hybrid").describe("hybrid = entity + concept-graph + BM25 fused; exact = BM25 keyword only"),
|
|
6110
|
+
hours: z15.number().int().min(1).max(720).optional().describe("Lookback window in hours; omit for no time limit"),
|
|
6111
|
+
limit: z15.number().int().min(1).max(50).default(20).describe("Max items returned")
|
|
6326
6112
|
},
|
|
6327
6113
|
handler: async (args, ctx) => {
|
|
6328
6114
|
const op = OPERATIONS["search.semantic"];
|
|
@@ -6375,7 +6161,7 @@ function buildSearchCommand() {
|
|
|
6375
6161
|
}
|
|
6376
6162
|
// src/verbs/sentiment.ts
|
|
6377
6163
|
import { Command as Command18, Option as Option16 } from "commander";
|
|
6378
|
-
import { z as
|
|
6164
|
+
import { z as z16 } from "zod";
|
|
6379
6165
|
var SCOPE_VALUES = [
|
|
6380
6166
|
"all_a",
|
|
6381
6167
|
"all_a_ex_st",
|
|
@@ -6399,8 +6185,8 @@ var sentimentSpec = {
|
|
|
6399
6185
|
name: "sentiment",
|
|
6400
6186
|
description: "Aggregate market sentiment indicators (limit-up/down counts, breadth, divergence index, top movers). Defaults to all_a_ex_st (all A-shares ex-ST). Pass `at_date` (YYYY-MM-DD) for any historical trading day; omit for today's latest snapshot. Backward-compat alias of `sentiment_overview` — prefer the latter in new agent code.",
|
|
6401
6187
|
inputSchema: {
|
|
6402
|
-
scope:
|
|
6403
|
-
at_date:
|
|
6188
|
+
scope: z16.enum(SCOPE_VALUES).default("all_a_ex_st").describe("Universe filter"),
|
|
6189
|
+
at_date: z16.string().regex(DATE_RE6).optional().describe("Trade date YYYY-MM-DD; omit for today's realtime snapshot")
|
|
6404
6190
|
},
|
|
6405
6191
|
handler: async (args, ctx) => {
|
|
6406
6192
|
const op = OPERATIONS["sentiment.overview"];
|
|
@@ -6417,8 +6203,8 @@ var sentimentOverviewSpec = {
|
|
|
6417
6203
|
name: "sentiment_overview",
|
|
6418
6204
|
description: "Aggregate sentiment snapshot for one trading day's latest minute: up/down/flat counts, limit-up/down, gt3/lt3 breadth, divergence index + label, MA20/50/200 breadth, 52w new high/low. `at_date` omitted = today realtime (Redis); explicit YYYY-MM-DD = historical from ClickHouse `market_breadth_intraday` last minute.",
|
|
6419
6205
|
inputSchema: {
|
|
6420
|
-
scope:
|
|
6421
|
-
at_date:
|
|
6206
|
+
scope: z16.enum(SCOPE_VALUES).default("all_a_ex_st").describe("Universe filter"),
|
|
6207
|
+
at_date: z16.string().regex(DATE_RE6).optional().describe("Trade date YYYY-MM-DD; omit for today realtime")
|
|
6422
6208
|
},
|
|
6423
6209
|
handler: async (args, ctx) => {
|
|
6424
6210
|
const op = OPERATIONS["sentiment.overview"];
|
|
@@ -6435,8 +6221,8 @@ var sentimentBreadthSpec = {
|
|
|
6435
6221
|
name: "sentiment_breadth",
|
|
6436
6222
|
description: "Intraday breadth time series for one trading day (up to 241 minute bars; 13:00 excluded due to sparse Sina ticks). `at_date` omitted = today (pre-open returns empty); explicit YYYY-MM-DD = historical replay. Returns per-minute rows of up/down/flat/limit_up/limit_down/breadth/divergence fields — same shape as `sentiment_overview` per row.",
|
|
6437
6223
|
inputSchema: {
|
|
6438
|
-
scope:
|
|
6439
|
-
at_date:
|
|
6224
|
+
scope: z16.enum(SCOPE_VALUES).default("all_a_ex_st").describe("Universe filter"),
|
|
6225
|
+
at_date: z16.string().regex(DATE_RE6).optional().describe("Trade date YYYY-MM-DD; omit for today")
|
|
6440
6226
|
},
|
|
6441
6227
|
handler: async (args, ctx) => {
|
|
6442
6228
|
const op = OPERATIONS["sentiment.breadth"];
|
|
@@ -6453,9 +6239,9 @@ var sentimentTurnoverSpec = {
|
|
|
6453
6239
|
name: "sentiment_turnover",
|
|
6454
6240
|
description: "Intraday turnover time series with `current_turnover` / `predicted_total` / `delta_vs_yesterday` headline fields. `at_date` omitted = today (pre-open returns nulls); explicit YYYY-MM-DD = historical. `days` (1-5) pulls that day + N-1 prior trading days for same-minute YoY comparison.",
|
|
6455
6241
|
inputSchema: {
|
|
6456
|
-
scope:
|
|
6457
|
-
at_date:
|
|
6458
|
-
days:
|
|
6242
|
+
scope: z16.enum(SCOPE_VALUES).default("all_a_ex_st").describe("Universe filter"),
|
|
6243
|
+
at_date: z16.string().regex(DATE_RE6).optional().describe("Trade date YYYY-MM-DD; omit for today"),
|
|
6244
|
+
days: z16.number().int().min(1).max(5).default(1).describe("at_date 当日 + 之前 days-1 天(1-5,默认 1)")
|
|
6459
6245
|
},
|
|
6460
6246
|
handler: async (args, ctx) => {
|
|
6461
6247
|
const op = OPERATIONS["sentiment.turnover"];
|
|
@@ -6550,19 +6336,20 @@ function buildSentimentCommand() {
|
|
|
6550
6336
|
}
|
|
6551
6337
|
// src/verbs/views.ts
|
|
6552
6338
|
import { Command as Command19, Option as Option17 } from "commander";
|
|
6553
|
-
import { z as
|
|
6339
|
+
import { z as z17 } from "zod";
|
|
6554
6340
|
var viewsSpec = {
|
|
6555
6341
|
name: "views",
|
|
6556
|
-
description: "PRIMARY research source for stock judgement: analyst views / sell-side reports / long-form opinion stream, with research_entity_id attribution. Prefer this over `news` when forming an investment opinion.
|
|
6342
|
+
description: "PRIMARY research source for stock judgement: analyst views / sell-side reports / long-form opinion stream, with research_entity_id attribution. Prefer this over `news` when forming an investment opinion. Returns `fields=compact` by default (ai_summary + first ~300 chars of content, `content_truncated` flag) — typically 20-50x smaller than full; pass fields='full' only when summaries are not enough. Recommended reading path: `digest` for a one-shot overview → this verb (compact) to scan → `report` for the full text of a single item (`full_text_available=true` means a parsed research report). AH dual-listing: for an A+H listed company pass the A-share canonical to get the consolidated coverage (most domestic analyst views attribute to the A-share security); use HK code only if the user explicitly asks for the HK perspective.",
|
|
6557
6343
|
inputSchema: {
|
|
6558
|
-
code:
|
|
6559
|
-
analyst:
|
|
6560
|
-
institution:
|
|
6561
|
-
since_days:
|
|
6562
|
-
from:
|
|
6563
|
-
to:
|
|
6564
|
-
offset:
|
|
6565
|
-
limit:
|
|
6344
|
+
code: z17.string().regex(/^((SSE|SZSE|BSE):[0-9]{6}|HK:[0-9]{5}|US:[A-Z][A-Z0-9.\-]{0,5})$/).optional().describe("Filter by security canonical_code (e.g. SSE:600519, HK:00700, US:AAPL)"),
|
|
6345
|
+
analyst: z17.string().optional().describe("Analyst Chinese name (exact / fuzzy)"),
|
|
6346
|
+
institution: z17.string().optional().describe("Broker / institution Chinese name"),
|
|
6347
|
+
since_days: z17.number().int().min(1).max(365).default(7).describe("Lookback in days. ≤30 = rolling feed; >30 auto-switches to range history " + "(needs a code/analyst/institution filter; Pro-only up to 365). For an explicit window use from/to."),
|
|
6348
|
+
from: z17.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("History range start (China date YYYY-MM-DD). Range mode: needs a filter; Pro-only up to 365 days back."),
|
|
6349
|
+
to: z17.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe("History range end (inclusive, China date; defaults to today). Use with from."),
|
|
6350
|
+
offset: z17.number().int().min(0).optional().describe("Pagination offset for paging through long history ranges."),
|
|
6351
|
+
limit: z17.number().int().min(1).max(100).default(30).describe("Max items per page"),
|
|
6352
|
+
fields: z17.enum(["compact", "full"]).optional().describe("Response shape: compact (default — ai_summary + first ~300 chars) or full (complete content)")
|
|
6566
6353
|
},
|
|
6567
6354
|
handler: async (args, ctx) => {
|
|
6568
6355
|
const op = OPERATIONS["views.recent"];
|
|
@@ -6586,6 +6373,8 @@ function buildViewsCallArgs(args) {
|
|
|
6586
6373
|
callArgs.institution = args.institution;
|
|
6587
6374
|
if (typeof args.offset === "number")
|
|
6588
6375
|
callArgs.offset = args.offset;
|
|
6376
|
+
if (args.fields === "compact" || args.fields === "full")
|
|
6377
|
+
callArgs.fields = args.fields;
|
|
6589
6378
|
const explicitRange = typeof args.from === "string" && args.from.length > 0;
|
|
6590
6379
|
if (explicitRange || sinceDays > 30) {
|
|
6591
6380
|
if (!hasFilter) {
|
|
@@ -6607,10 +6396,10 @@ var reportSpec = {
|
|
|
6607
6396
|
name: "report",
|
|
6608
6397
|
description: "Fetch the FULL research-report text behind a view (mineru-parsed long-form), for when the `views` summary is not enough. Only works on views where `full_text_available=true` (gdrive sell-side reports). Two-step usage: default `format=outline` returns a few-KB heading map + total_chars + each heading's char_offset; then call `format=full` with `offset` (e.g. an outline char_offset) to read the body in pages — follow `next_offset` to page through large docs instead of pulling everything at once.",
|
|
6609
6398
|
inputSchema: {
|
|
6610
|
-
view_id:
|
|
6611
|
-
format:
|
|
6612
|
-
offset:
|
|
6613
|
-
max_chars:
|
|
6399
|
+
view_id: z17.string().regex(/^[0-9]+$/).describe("View id from `views` items[].id (must have full_text_available=true)"),
|
|
6400
|
+
format: z17.enum(["outline", "full"]).default("outline").describe("outline=heading map (default); full=body slice"),
|
|
6401
|
+
offset: z17.number().int().min(0).default(0).describe("full mode: start char offset (use an outline char_offset)"),
|
|
6402
|
+
max_chars: z17.number().int().min(1).max(80000).default(40000).describe("full mode: max chars per page (hard cap 80000)")
|
|
6614
6403
|
},
|
|
6615
6404
|
handler: async (args, ctx) => {
|
|
6616
6405
|
const op = OPERATIONS["views.document"];
|
|
@@ -6648,6 +6437,10 @@ function buildViewsCommand() {
|
|
|
6648
6437
|
cmd.addOption(new Option17("--to <date>", "History range end YYYY-MM-DD (inclusive; default today)"));
|
|
6649
6438
|
cmd.addOption(new Option17("--offset <n>", "Pagination offset for long history").default("0"));
|
|
6650
6439
|
cmd.addOption(new Option17("--limit <n>", "Max items (1-100)").default("30"));
|
|
6440
|
+
cmd.addOption(new Option17("--fields <mode>", "Response shape: compact (default) or full").choices([
|
|
6441
|
+
"compact",
|
|
6442
|
+
"full"
|
|
6443
|
+
]));
|
|
6651
6444
|
cmd.action(async (opts) => {
|
|
6652
6445
|
if (!OPERATIONS["views.recent"]) {
|
|
6653
6446
|
emitVerbError("internal_error", "views.recent missing from codegen", undefined, 2);
|
|
@@ -6667,6 +6460,8 @@ function buildViewsCommand() {
|
|
|
6667
6460
|
args.from = opts.from;
|
|
6668
6461
|
if (opts.to)
|
|
6669
6462
|
args.to = opts.to;
|
|
6463
|
+
if (opts.fields)
|
|
6464
|
+
args.fields = opts.fields;
|
|
6670
6465
|
await executeVerb(async (ctx) => viewsSpec.handler(args, ctx));
|
|
6671
6466
|
});
|
|
6672
6467
|
return cmd;
|
|
@@ -6700,6 +6495,7 @@ var ALL_VERB_SPECS = [
|
|
|
6700
6495
|
quoteSpec,
|
|
6701
6496
|
marketStatusSpec,
|
|
6702
6497
|
marketMoversSpec,
|
|
6498
|
+
indexSnapshotSpec,
|
|
6703
6499
|
viewsSpec,
|
|
6704
6500
|
reportSpec,
|
|
6705
6501
|
newsSpec,
|
|
@@ -6734,7 +6530,8 @@ var ALL_VERB_SPECS = [
|
|
|
6734
6530
|
financialsReportsSpec,
|
|
6735
6531
|
financialsSeriesSpec,
|
|
6736
6532
|
ownershipShowSpec,
|
|
6737
|
-
ownershipLockupsSpec
|
|
6533
|
+
ownershipLockupsSpec,
|
|
6534
|
+
capabilitiesSpec
|
|
6738
6535
|
];
|
|
6739
6536
|
|
|
6740
6537
|
// src/tools/mcp.ts
|
|
@@ -7521,375 +7318,283 @@ function buildDoctorCommand() {
|
|
|
7521
7318
|
|
|
7522
7319
|
// src/tools/schema.ts
|
|
7523
7320
|
import { Command as Command27 } from "commander";
|
|
7524
|
-
import { z as
|
|
7321
|
+
import { z as z18 } from "zod";
|
|
7525
7322
|
|
|
7526
7323
|
// src/_generated/help.ts
|
|
7527
7324
|
var HELP = {
|
|
7528
7325
|
"agent.session-end": {
|
|
7529
|
-
summary: "
|
|
7530
|
-
description: "
|
|
7326
|
+
summary: "Close a billable agent session.",
|
|
7327
|
+
description: "Closes a session opened by `/v1/agent/session/start` and commits its final usage.",
|
|
7531
7328
|
example: "echopai agent session-end VALUE"
|
|
7532
7329
|
},
|
|
7533
7330
|
"agent.session-start": {
|
|
7534
|
-
summary: "
|
|
7535
|
-
description: "
|
|
7331
|
+
summary: "Open a billable agent session.",
|
|
7332
|
+
description: "Opens a billable session for an agent credential and returns a session_id that groups subsequent calls into a single billable unit. Requires an `Idempotency-Key` header.",
|
|
7536
7333
|
example: "echopai agent session-start --agent-id agent-prod-1 --budget-usd 1.0"
|
|
7537
7334
|
},
|
|
7538
7335
|
"agent.session-usage": {
|
|
7539
|
-
summary: "Get cumulative usage
|
|
7540
|
-
description: "
|
|
7336
|
+
summary: "Get cumulative usage for an agent session.",
|
|
7337
|
+
description: "Returns the cumulative billable call count and per-scope quota consumption for the given session.",
|
|
7541
7338
|
example: "echopai agent session-usage VALUE"
|
|
7542
7339
|
},
|
|
7543
7340
|
"announcements.detail": {
|
|
7544
|
-
summary: "
|
|
7545
|
-
description: "
|
|
7341
|
+
summary: "Get a single announcement by id.",
|
|
7342
|
+
description: "Returns the full content of one announcement: body (markdown and plain text), metadata, and parse status.",
|
|
7546
7343
|
example: "echopai announcements detail VALUE"
|
|
7547
7344
|
},
|
|
7548
7345
|
"announcements.feed": {
|
|
7549
|
-
summary: "List recent A-share announcements",
|
|
7550
|
-
description: "
|
|
7346
|
+
summary: "List recent A-share announcements.",
|
|
7347
|
+
description: "Returns a feed of recent A-share corporate announcements, sorted by publication date descending. Filter by `type` or `since`. Requires the `announcements:read` scope.",
|
|
7551
7348
|
example: "echopai announcements feed"
|
|
7552
7349
|
},
|
|
7553
7350
|
"announcements.search": {
|
|
7554
|
-
summary: "
|
|
7555
|
-
description: "
|
|
7351
|
+
summary: "Search A-share announcements.",
|
|
7352
|
+
description: "Hybrid search over A-share announcements: structured filtering by security name or code, combined with full-text keyword search (over title, AI summary, and the first ~1500 characters of the body). A query containing a 6-digit code or an embedded security name is filtered by that security; remaining free text is ranked by relevance with time decay; a pure code or name lists results by publication date descending. Requires the `announcements:read` scope.",
|
|
7556
7353
|
example: "echopai announcements search --q 新华医疗 回购"
|
|
7557
7354
|
},
|
|
7558
7355
|
"announcements.stock": {
|
|
7559
|
-
summary: "List announcements for
|
|
7560
|
-
description: "
|
|
7356
|
+
summary: "List announcements for one security.",
|
|
7357
|
+
description: "Returns the announcement history for one A-share security over a date window. Accepts a 6-digit code or canonical form (e.g. `SSE:600519`). Requires the `announcements:read` scope.",
|
|
7561
7358
|
example: "echopai announcements stock --code SSE:600519"
|
|
7562
7359
|
},
|
|
7563
7360
|
"auth.whoami": {
|
|
7564
|
-
summary: "
|
|
7565
|
-
description:
|
|
7566
|
-
rate_limit, allowed_clients, agent_budget (if kind=agent), api_version,
|
|
7567
|
-
feature_flags. Any valid JWT can call — no specific scope required.
|
|
7568
|
-
|
|
7569
|
-
CLI/MCP call this once at startup, cache 5 minutes in-process, and use
|
|
7570
|
-
the response to derive \`verbs.available\` (intersection of curated verb
|
|
7571
|
-
scopes with token scopes) and to populate \`echopai doctor\` checks.
|
|
7572
|
-
|
|
7573
|
-
See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §5.1.
|
|
7574
|
-
`,
|
|
7361
|
+
summary: "Introspect the calling token (capability discovery).",
|
|
7362
|
+
description: "Returns the calling token's kind, scopes, audience, app metadata, rate limit, allowed clients, agent budget (when kind=agent), API version, and feature flags. Any valid token may call this; no specific scope is required. Clients typically call it once at startup and cache the result briefly to determine which commands are available.",
|
|
7575
7363
|
example: "echopai auth whoami"
|
|
7576
7364
|
},
|
|
7577
7365
|
"bars.daily": {
|
|
7578
|
-
summary: "
|
|
7579
|
-
description: "
|
|
7366
|
+
summary: "List daily OHLC bars for one A-share security.",
|
|
7367
|
+
description: "Returns daily open/high/low/close/volume/turnover for one A-share security over a date range (canonical code, e.g. `SSE:600519`). End-of-day data. Requires the `bars:30d` scope (last 30 trading days) or `bars:full` scope (full history).",
|
|
7580
7368
|
example: "echopai bars daily --code SSE:600519 --from 2026-01-01 --to 2026-05-01"
|
|
7581
7369
|
},
|
|
7582
7370
|
"bars.daily-batch": {
|
|
7583
|
-
summary: "Batch daily OHLC bars for up to 100
|
|
7584
|
-
description: "
|
|
7371
|
+
summary: "Batch daily OHLC bars for up to 100 securities.",
|
|
7372
|
+
description: "Returns daily OHLC bars for multiple A-share securities in one call: up to 100 codes and up to a one-year date range. Responses use a partial-success envelope: codes the token may not access are reported in `errors[]`, the rest in `items[]` (with an empty `bars[]` when no data is found), preserving input order. Requires the `bars:30d` or `bars:full` scope.",
|
|
7585
7373
|
example: "echopai bars daily-batch --codes ['SSE:600519', 'SZSE:000001']"
|
|
7586
7374
|
},
|
|
7587
7375
|
"bars.minute": {
|
|
7588
|
-
summary: "
|
|
7589
|
-
description: "
|
|
7376
|
+
summary: "List minute OHLC bars for one A-share security.",
|
|
7377
|
+
description: "Returns minute-level OHLC bars for one A-share security on a single trade date (canonical code, e.g. `SSE:600519`). Requires the `bars:30d` or `bars:full` scope.",
|
|
7590
7378
|
example: "echopai bars minute --code SSE:600519 --date 2026-05-09"
|
|
7591
7379
|
},
|
|
7592
7380
|
"bars.minute-batch": {
|
|
7593
|
-
summary: "Batch minute OHLC bars for up to 20
|
|
7594
|
-
description: "
|
|
7381
|
+
summary: "Batch minute OHLC bars for up to 20 securities.",
|
|
7382
|
+
description: "Returns minute-level OHLC bars for multiple A-share securities in one call: up to 20 codes and up to a 7 calendar-day (~5 trading-day) range. Responses use a partial-success envelope: codes the token may not access are reported in `errors[]`, the rest in `items[]` with a flat `bars[]` array where each bar carries its own `trade_date` for client-side grouping. Requires the `bars:30d` or `bars:full` scope.",
|
|
7595
7383
|
example: "echopai bars minute-batch --codes ['SSE:600519', 'SZSE:000001']"
|
|
7596
7384
|
},
|
|
7385
|
+
"capabilities.show": {
|
|
7386
|
+
summary: "Capability changelog and API version discovery.",
|
|
7387
|
+
description: "Returns the current API spec version plus a machine-readable changelog of capability changes (new endpoints, new fields, behavior fixes), newest first. Check it at session start — or after an unexpected response shape — to discover capabilities added since your integration was written. Free and unauthenticated.",
|
|
7388
|
+
example: "echopai capabilities show"
|
|
7389
|
+
},
|
|
7597
7390
|
"concepts.alerts": {
|
|
7598
|
-
summary: "
|
|
7599
|
-
description:
|
|
7600
|
-
- big_move: abs(pct_change) > 3%
|
|
7601
|
-
- limit_up_cluster: limit_up_count >= 3 AND stock_count >= 5
|
|
7602
|
-
See PLAN_CONCEPT_INDUSTRY_QUOTE §5.5 "异动检测与推送".
|
|
7603
|
-
`,
|
|
7391
|
+
summary: "List currently active concept alerts.",
|
|
7392
|
+
description: "Returns the live set of concept alerts. Two rules fire: `big_move` when absolute percent change exceeds 3%, and `limit_up_cluster` when a concept has at least 3 limit-up members across at least 5 member stocks.",
|
|
7604
7393
|
example: "echopai concepts alerts"
|
|
7605
7394
|
},
|
|
7606
7395
|
"concepts.alerts-history": {
|
|
7607
|
-
summary: "
|
|
7608
|
-
description: "
|
|
7396
|
+
summary: "List recent concept alert history.",
|
|
7397
|
+
description: "Returns historical concept alert events (default: last 24 hours). Filter by rule (`big_move` / `limit_up_cluster`) and time window. Useful for reviewing how concept activity evolved over a period.",
|
|
7609
7398
|
example: "echopai concepts alerts-history"
|
|
7610
7399
|
},
|
|
7611
7400
|
"concepts.daily-bars": {
|
|
7612
|
-
summary: "
|
|
7613
|
-
description:
|
|
7614
|
-
breadth fields, and is_backfilled flag. See PLAN §5.4 algorithm.
|
|
7615
|
-
`,
|
|
7401
|
+
summary: "List daily bars for a concept index.",
|
|
7402
|
+
description: "Returns daily OHLC for a concept index (index points, not an average of member stock prices), along with breadth fields and a backfill flag. The concept index is a chain-linked equal-weight return series with a base of 1000.",
|
|
7616
7403
|
example: "echopai concepts daily-bars VALUE"
|
|
7617
7404
|
},
|
|
7618
7405
|
"concepts.list": {
|
|
7619
|
-
summary: "List concepts with live snapshot
|
|
7620
|
-
description: "
|
|
7406
|
+
summary: "List concepts with their live snapshot.",
|
|
7407
|
+
description: "Lists market concepts (themes/sectors) joined with their latest real-time snapshot, falling back to the last close and then to recent daily data when live ticks are unavailable. Each item carries a `_source` freshness indicator. Live fields include percent change, index value, advancing/declining counts, limit-up count, turnover amount, 3-minute momentum, and `main_net_in` (net main-capital inflow in CNY, which may be negative for net outflow and null when unavailable). The concept index is a chain-linked equal-weight return series with a base of 1000. During the 9:00–9:14 pre-open window, live data is suppressed and a loading state is returned.",
|
|
7621
7408
|
example: "echopai concepts list"
|
|
7622
7409
|
},
|
|
7623
7410
|
"concepts.minute-bars": {
|
|
7624
|
-
summary: "
|
|
7625
|
-
description: "
|
|
7411
|
+
summary: "List minute bars for a concept index.",
|
|
7412
|
+
description: "Returns minute-level OHLC for a concept index (chain-linked equal-weight return series, base 1000), up to 7 days per request.",
|
|
7626
7413
|
example: "echopai concepts minute-bars VALUE"
|
|
7627
7414
|
},
|
|
7628
7415
|
"concepts.news": {
|
|
7629
|
-
summary: "
|
|
7630
|
-
description:
|
|
7631
|
-
concept name and full_name. Long-term: news AI tagging.
|
|
7632
|
-
`,
|
|
7416
|
+
summary: "List news related to a concept.",
|
|
7417
|
+
description: "Returns recent news whose title or body mentions the concept's name. Use it to see what is currently driving a theme.",
|
|
7633
7418
|
example: "echopai concepts news VALUE"
|
|
7634
7419
|
},
|
|
7635
7420
|
"concepts.show": {
|
|
7636
|
-
summary: "
|
|
7637
|
-
description: "
|
|
7421
|
+
summary: "Get concept detail with member securities.",
|
|
7422
|
+
description: "Returns detail for one concept: metadata (full name, source, status, approval date, first-listed date) plus its current member securities with their latest snapshots.",
|
|
7638
7423
|
example: "echopai concepts show VALUE"
|
|
7639
7424
|
},
|
|
7640
7425
|
"concepts.snapshot": {
|
|
7641
|
-
summary: "Bulk
|
|
7642
|
-
description: "
|
|
7426
|
+
summary: "Bulk real-time snapshot of concepts.",
|
|
7427
|
+
description: "Returns real-time snapshots for concepts, with two modes. With `codes=`, each requested concept id is resolved via real-time → last-close → recent-daily fallback so every requested id is populated. Without `codes`, it returns a best-effort dump of all concepts that currently have a real-time or last-close snapshot; concepts absent from both are not backfilled (use `GET /v1/concepts` if you need every known concept). Each item carries a `_source` freshness indicator. During the 9:00–9:14 pre-open window, live data is suppressed and an empty list is returned.",
|
|
7643
7428
|
example: "echopai concepts snapshot"
|
|
7644
7429
|
},
|
|
7645
7430
|
"concepts.views": {
|
|
7646
|
-
summary: "
|
|
7647
|
-
description: "
|
|
7431
|
+
summary: "List analyst views associated with a concept.",
|
|
7432
|
+
description: "Returns analyst views linked to this concept (with AI processing complete), sorted by publication date descending.",
|
|
7648
7433
|
example: "echopai concepts views VALUE"
|
|
7649
7434
|
},
|
|
7650
7435
|
"digest.get": {
|
|
7651
|
-
summary: "
|
|
7652
|
-
description:
|
|
7653
|
-
real-time quote, valuation snapshot (PE/PB/PS/换手率/股息率/量比 等 14 字段),
|
|
7654
|
-
market sentiment context, and supplementary news.
|
|
7655
|
-
Partial-failure tolerant:
|
|
7656
|
-
each bucket is independently fetched and per-bucket failures surface
|
|
7657
|
-
in \`meta.partial_failures[]\` rather than poisoning the response. If
|
|
7658
|
-
every sub-bucket fails the endpoint returns 502.
|
|
7659
|
-
|
|
7660
|
-
Bucket scopes are checked *per bucket* (not at gateway level): a
|
|
7661
|
-
token with only \`views:read\` gets the views bucket populated and the
|
|
7662
|
-
rest reported as \`scope_insufficient\` partial failures. This mirrors
|
|
7663
|
-
the CLI fan-out contract exactly so \`echopai digest\` can either call
|
|
7664
|
-
this endpoint (preferred, single round-trip) or fall back to local
|
|
7665
|
-
fan-out without behavior drift.
|
|
7666
|
-
|
|
7667
|
-
See \`docs/PLAN_CLI_V2_AGENT_SURFACE.md\` §3.3 (digest spec) and §11
|
|
7668
|
-
Phase 5.2 (server endpoint).
|
|
7669
|
-
`,
|
|
7436
|
+
summary: "Build a one-shot research digest for one security.",
|
|
7437
|
+
description: "Composite endpoint that, in a single call, returns separated sections for one security: analyst views (the primary research source), a real-time quote, a valuation snapshot (PE/PB/PS, turnover rate, dividend yield, volume ratio, and ~14 fields in total), market sentiment context, and supplementary news. Each section is fetched independently and per-section failures are reported in `meta.partial_failures[]` instead of failing the whole call; the endpoint returns 502 only if every section fails. Scopes are enforced per section, so a token with only `views:read` receives the views section and sees the rest reported as scope-insufficient. Use this when you want a single broad overview of a security (canonical code, e.g. `SSE:600519`).",
|
|
7670
7438
|
example: "echopai digest get HK:00700"
|
|
7671
7439
|
},
|
|
7672
7440
|
"financials.pit": {
|
|
7673
|
-
summary: "
|
|
7674
|
-
description: "
|
|
7441
|
+
summary: "Get point-in-time fundamentals for one security at a date.",
|
|
7442
|
+
description: "Returns the most recent financial report that was publicly available on a given date for one A-share security (canonical code, e.g. `SSE:600519`) — i.e. announcement date on or before `date`, with a conservative 90-day fallback when the announcement date is unknown. Designed to avoid look-ahead bias in backtests and quantitative strategies. Fields include EPS (basic / non-recurring / diluted), BPS, ROE, gross margin, revenue, net profit, total assets, and parent-company equity (~25 core fields).",
|
|
7675
7443
|
example: "echopai financials pit --code SSE:600519 --date 2024-11-01"
|
|
7676
7444
|
},
|
|
7677
7445
|
"financials.quote-snapshot": {
|
|
7678
|
-
summary: "
|
|
7679
|
-
description: "
|
|
7446
|
+
summary: "Get a real-time valuation snapshot for one security.",
|
|
7447
|
+
description: "Returns a one-stop valuation snapshot (14 fields) for one A-share security (canonical code, e.g. `SSE:600519`), combining real-time prices with point-in-time fundamentals so figures are free of look-ahead bias. Fields: valuation (`pe`, `pe_ttm`, `pb`, `ps`, `ps_ttm`); share counts in 10k shares (`total_share`, `float_share`, `free_share`); market cap in 10k CNY (`total_mv`, `circ_mv`); liquidity (`turnover_rate`, `turnover_rate_f` in %, `volume_ratio` as a multiple); and dividend yield (`dv_ratio`, `dv_ttm` in %). Leave `date` empty for a real-time snapshot, or pass `date=YYYY-MM-DD` to value as of that day's close (useful for historical checks and backtests).",
|
|
7680
7448
|
example: "echopai financials quote-snapshot --code SSE:600519 --date 2026-05-13"
|
|
7681
7449
|
},
|
|
7682
7450
|
"financials.reports": {
|
|
7683
|
-
summary: "
|
|
7684
|
-
description: "
|
|
7451
|
+
summary: "List recent financial reports for one security.",
|
|
7452
|
+
description: "Returns core indicators for the most recent N financial reports of one A-share security (EPS/BPS/ROE, gross margin, revenue, net profit, total assets, parent equity, operating cash flow, total shares, and ~25 fields in total). Filter by `kind` for quarterly / interim / annual reports. Each report's `announce_date` indicates when it became publicly visible, which is useful for point-in-time analysis. Note: `kind=preliminary` does not exist as a separate report row — earnings forecasts and flash reports are exposed as metric fields (e.g. `forecast_ni_lower`, `forecast_ni_upper`, `express_ni_parent`, `express_revenue`) via `financials.series`, so `kind=preliminary` returns an empty list with an explanatory note.",
|
|
7685
7453
|
example: "echopai financials reports --code SSE:600519"
|
|
7686
7454
|
},
|
|
7687
7455
|
"financials.series": {
|
|
7688
|
-
summary: "
|
|
7689
|
-
description: "
|
|
7456
|
+
summary: "Get a time series of one financial metric.",
|
|
7457
|
+
description: "Returns the historical time series of a single financial metric for one A-share security, ordered by reporting period. `metric` is an indicator field name (e.g. `roe_simple`, `revenue`, `ni_parent`, `debt_asset_ratio`, `gross_margin`, `eps_basic`; ~150 metrics available). Use it to chart a multi-year trend for one company or to compare the same metric across several securities.",
|
|
7690
7458
|
example: "echopai financials series --code SSE:600519 --metric roe_simple"
|
|
7691
7459
|
},
|
|
7692
7460
|
"index.daily-bars": {
|
|
7693
|
-
summary: "
|
|
7694
|
-
description: "
|
|
7461
|
+
summary: "List daily OHLC bars for one A-share index.",
|
|
7462
|
+
description: "Returns daily OHLC for one A-share index (e.g. 上证综指 `SSE:000001`, 深证成指 `SZSE:399001`, 沪深300 `SSE:000300`, 北证50 `BSE:899050`, CSI series such as `CSI:000922`). Same semantics as `/v1/bars/daily`, but indices have no stock-specific fields such as turnover rate or suspension flag.",
|
|
7695
7463
|
example: "echopai index daily-bars --code SSE:000001 --from 2024-01-01 --to 2024-12-31"
|
|
7696
7464
|
},
|
|
7697
7465
|
"index.minute-bars": {
|
|
7698
|
-
summary: "
|
|
7699
|
-
description: "
|
|
7466
|
+
summary: "List minute OHLC bars for one A-share index.",
|
|
7467
|
+
description: "Returns 1-minute OHLC for one A-share index over a date range of up to 7 days. Each bar includes bar time, trade date, OHLC, volume, amount, and percent change.",
|
|
7700
7468
|
example: "echopai index minute-bars --code SSE:000001"
|
|
7701
7469
|
},
|
|
7702
7470
|
"index.snapshot": {
|
|
7703
|
-
summary: "
|
|
7704
|
-
description: "Returns the latest real-time snapshot for the 172 indices that
|
|
7471
|
+
summary: "Snapshot real-time quotes for A-share indices.",
|
|
7472
|
+
description: "Returns the latest real-time snapshot for the 172 A-share indices that have a live quote feed (SSE / SZSE / BSE, including 北证50 `BSE:899050`). The snapshot refreshes roughly every 15 seconds during market hours; outside trading hours the last intraday snapshot is returned. Use `codes` (canonical format, e.g. `SSE:000001`) to narrow to a subset, or omit it to receive all indices. Note: CSI-series indices (e.g. `CSI:000922`) have no live quote feed and are not returned here. Requires a `quote:l1`, `quote:l2`, or `quote:delayed` scope.",
|
|
7705
7473
|
example: "echopai index snapshot --codes SSE:000001,SZSE:399001,BSE:899050"
|
|
7706
7474
|
},
|
|
7707
|
-
"industries.alerts": {
|
|
7708
|
-
summary: "Currently active industry alerts",
|
|
7709
|
-
description: "Currently active industry alerts (big_move / limit_up_cluster). Same rule set as concepts.",
|
|
7710
|
-
example: "echopai industries alerts"
|
|
7711
|
-
},
|
|
7712
|
-
"industries.daily-bars": {
|
|
7713
|
-
summary: "Industry index daily bars",
|
|
7714
|
-
description: "Industry index daily OHLC (chain-linked equal-weight, base = 1000). Path key format `<sw_industry_code>:<sw_level>` (e.g. `401001:1`).",
|
|
7715
|
-
example: "echopai industries daily-bars 401001:1"
|
|
7716
|
-
},
|
|
7717
|
-
"industries.list": {
|
|
7718
|
-
summary: "List industries (申万 L1/L2) with hot/warm fallback",
|
|
7719
|
-
description: "Industry index list joining CH `v_industry_meta` with Redis snapshot.\n申万一级 (level=1) ≈ 127 industries, 申万二级 (level=2) ≈ 348.\nChain-linked equal-weight algorithm identical to concepts (PLAN §5.4).\n\nRead order per industry (mirrors `/v1/concepts`, PR #442):\n 1. `industry_snapshots:latest` (hot, TTL 5min)\n 2. `industry_snapshots:last_close` (warm, TTL 7d)\n 3. CH `v_industry_daily_bars` argMax\n9:00–9:14 reset window suppresses hot+warm (loading state).\nEach item carries `_source` ∈ {`latest`, `last_close`, `ch_daily`, `miss`}.\n",
|
|
7720
|
-
example: "echopai industries list"
|
|
7721
|
-
},
|
|
7722
|
-
"industries.show": {
|
|
7723
|
-
summary: "Industry detail (meta + today members)",
|
|
7724
|
-
description: "Path key format: `<sw_industry_code>:<sw_level>` (e.g. `401001:1`).",
|
|
7725
|
-
example: "echopai industries show 401001:1"
|
|
7726
|
-
},
|
|
7727
|
-
"industries.snapshot": {
|
|
7728
|
-
summary: "Bulk Redis snapshot of industries (hot/warm union)",
|
|
7729
|
-
description: "Mirrors `/v1/concepts/snapshot` contract (PR #442 review 二轮):\n\n- **With `codes=`** (per-key completeness): hot → warm → CH fallback\n per industry; missing keys populated.\n- **Without `codes`** (best-effort dump): union of\n `industry_snapshots:latest` and `industry_snapshots:last_close`\n Redis hashes. Missing industries are **not** backfilled from CH; use\n GET `/v1/industries` for a fully populated list.\n\n9:00–9:14 reset window suppresses both Redis hashes and CH fallback.\nEach item carries `_source` ∈ {`latest`, `last_close`, `ch_daily`}.\n申万一级 (level=1) ≈ 127 industries, 申万二级 (level=2) ≈ 348.\n",
|
|
7730
|
-
example: "echopai industries snapshot"
|
|
7731
|
-
},
|
|
7732
7475
|
"limit-up.analysis": {
|
|
7733
|
-
summary: "
|
|
7734
|
-
description:
|
|
7476
|
+
summary: "Get LLM attribution for limit-up stocks.",
|
|
7477
|
+
description: "Returns LLM-generated attribution for each limit-up stock: the leading theme (`leading_concept`), concept tags, and a reason explaining why it hit the limit. Themes are inferred by an LLM from the latest research, institutional views, and news, so they may include brand-new themes; results refresh automatically at six points each trading day, with later runs refining earlier ones. This complements the limit-up pool, which tells you which stocks limited up; this endpoint tells you why and under which theme. Note: when `trade_date` is omitted, the latest attributed trading day is returned — before today's first run completes (around 09:47 Beijing time) this may be the previous trading day rather than empty, so pass an explicit `trade_date` for today and verify the `trade_date` / `generated_at` fields. Requires the `market:read` scope or any `quote:*` scope.",
|
|
7735
7478
|
example: "echopai limit-up analysis"
|
|
7736
7479
|
},
|
|
7737
7480
|
"limit-up.history": {
|
|
7738
|
-
summary: "A-share limit-up daily trend
|
|
7739
|
-
description: "
|
|
7481
|
+
summary: "Get the A-share limit-up daily trend.",
|
|
7482
|
+
description: "Returns the daily limit-up trend over the last N trading days: per-day limit-up count, highest consecutive-board height, and seal-break count. Sorted by trade date ascending (oldest first). Requires a `quote:*` scope.",
|
|
7740
7483
|
example: "echopai limit-up history"
|
|
7741
7484
|
},
|
|
7742
7485
|
"limit-up.pool": {
|
|
7743
|
-
summary: "A-share limit-up pool
|
|
7744
|
-
description: "
|
|
7486
|
+
summary: "List the A-share limit-up pool for a trade date.",
|
|
7487
|
+
description: "Returns per-stock detail for the limit-up pool on the current (or specified `trade_date`) trading day: first/last seal time, final percent change, seal amount and seal volume, number of times the seal broke, consecutive limit-up days, in-pool statistics over N days, one-line-board flag, current status (limit_up / broken), and sector classification. Sorted by consecutive limit-up days, then in-pool board count, then seal amount (all descending). Before 9:00 the previous trading day's data is returned; during 9:00–9:14 an empty result is returned; from 9:15 today's data is available. Requires a `quote:*` scope.",
|
|
7745
7488
|
example: "echopai limit-up pool"
|
|
7746
7489
|
},
|
|
7747
7490
|
"limit-up.summary": {
|
|
7748
|
-
summary: "A-share limit-up
|
|
7749
|
-
description: "
|
|
7491
|
+
summary: "Summarize A-share limit-up activity for a trade date.",
|
|
7492
|
+
description: "Returns aggregate limit-up statistics for the trade date: limit-up count, seal-break count, limit-down count, the highest consecutive-board height, and a height ladder (`ladder: [{ height, count }, ...]`). The height ladder counts only stocks currently sealed at limit-up. Pre-open fallback follows the same rules as the limit-up pool. Requires a `quote:*` scope.",
|
|
7750
7493
|
example: "echopai limit-up summary"
|
|
7751
7494
|
},
|
|
7752
7495
|
"market.status": {
|
|
7753
|
-
summary: "
|
|
7754
|
-
description: "
|
|
7496
|
+
summary: "Get the current A-share market session state.",
|
|
7497
|
+
description: "Returns the current A-share trading session (pre-open / open / lunch / closed), the current and next trading day, and a holiday flag. Requires the `market:read` scope or any `quote:*` scope.",
|
|
7755
7498
|
example: "echopai market status"
|
|
7756
7499
|
},
|
|
7757
7500
|
"news.feed": {
|
|
7758
|
-
summary: "List recent news
|
|
7759
|
-
description: "
|
|
7501
|
+
summary: "List recent news.",
|
|
7502
|
+
description: "Returns recent news. Equivalent to `/v1/news/list`; retained for backward compatibility. Partner/agent callers receive `fields=compact` by default (id, title, ai_summary, tagged securities, first ~300 chars of content); pass `fields=full` for complete content.",
|
|
7760
7503
|
example: "echopai news feed"
|
|
7761
7504
|
},
|
|
7762
7505
|
"news.get": {
|
|
7763
|
-
summary: "
|
|
7764
|
-
description: "
|
|
7506
|
+
summary: "Get a single news item by id.",
|
|
7507
|
+
description: "Returns the full content of one news item: title, content snippet, and tagged securities.",
|
|
7765
7508
|
example: "echopai news get VALUE"
|
|
7766
7509
|
},
|
|
7767
7510
|
"news.list": {
|
|
7768
|
-
summary: "List news mentioning
|
|
7769
|
-
description: "
|
|
7511
|
+
summary: "List news mentioning one security.",
|
|
7512
|
+
description: "Returns news items mentioning a specific A-share security, ordered by publication date descending. Requires the `news:read` scope.",
|
|
7770
7513
|
example: "echopai news list --security HK:00700"
|
|
7771
7514
|
},
|
|
7772
7515
|
"news.search": {
|
|
7773
|
-
summary: "Full-text search recent news",
|
|
7774
|
-
description: "Full-text search recent news
|
|
7516
|
+
summary: "Full-text search recent news.",
|
|
7517
|
+
description: "Full-text search over recent news and market briefs. Returns title, publication date, snippet, and tagged securities. Requires the `news:read` scope. Note: news fields are user-generated; `meta.untrusted_text_fields` lists fields that should be sanitized before being passed to an LLM.",
|
|
7775
7518
|
example: "echopai news search --query 光伏龙头"
|
|
7776
7519
|
},
|
|
7777
7520
|
"ownership.lockups": {
|
|
7778
|
-
summary: "Scan upcoming share-lockup expirations
|
|
7779
|
-
description:
|
|
7780
|
-
digest 给不了(digest 是单 code 维度)。min_pct 过滤小额解禁,limit 控量。
|
|
7781
|
-
`,
|
|
7521
|
+
summary: "Scan upcoming share-lockup expirations market-wide.",
|
|
7522
|
+
description: "Scans the whole market for share lockups expiring within the next `days` days, sorted by unlock date ascending then by unlocking ratio descending — a forward-looking selling-pressure screen across all securities. Use `min_pct` to filter out small unlocks and `limit` to cap the result size. T+1 data.",
|
|
7782
7523
|
example: "echopai ownership lockups"
|
|
7783
7524
|
},
|
|
7784
7525
|
"ownership.show": {
|
|
7785
|
-
summary: "
|
|
7786
|
-
description:
|
|
7787
|
-
+ 未来 30 天限售解禁」。源 Tushare(T+1),落 PG 专表幂等同步。
|
|
7788
|
-
|
|
7789
|
-
- shareholder_transactions:增减持回看 txn_days 天,含净增减股数/比例 +
|
|
7790
|
-
增减笔数 + 明细(方向/股东/均价/区间)。
|
|
7791
|
-
- share_repurchases:回购回看 repurchase_days 天,含在进行笔数 + 已执行
|
|
7792
|
-
累计金额/股数(仅计 in_progress/completed)+ 最新进度 + 明细。
|
|
7793
|
-
- lockup_expirations:解禁前瞻 lockup_days 天(unlock_date ∈ [today,
|
|
7794
|
-
today+N]),含合计解禁股数/占比 + 最近解禁日 + 明细。前瞻抛压预警。
|
|
7795
|
-
|
|
7796
|
-
枚举 slug(direction / holder_category / status / lockup_type)见
|
|
7797
|
-
docs/OWNERSHIP_EVENTS.md。
|
|
7798
|
-
`,
|
|
7526
|
+
summary: "Get ownership events for one security.",
|
|
7527
|
+
description: "Returns a structured three-in-one view of ownership events for one A-share security (canonical code, e.g. `SSE:600519`): recent shareholder transactions, recent share repurchases, and upcoming lockup expirations. T+1 data. Shareholder transactions look back `txn_days` days and include net change in shares/ratio, transaction count, and per-transaction detail (direction, holder, average price, date range). Repurchases look back `repurchase_days` days and include in-progress count, cumulative executed amount/shares, latest progress, and detail. Lockup expirations look ahead `lockup_days` days and include total unlocking shares/ratio, the nearest unlock date, and detail — useful as a forward-looking selling-pressure warning. Enum values (direction, holder category, status, lockup type) are documented in the response schema.",
|
|
7799
7528
|
example: "echopai ownership show --code SSE:600519"
|
|
7800
7529
|
},
|
|
7801
|
-
"payment.plans": {
|
|
7802
|
-
summary: "List subscription plans",
|
|
7803
|
-
description: "返回订阅计划清单(plan_id + 价格 + 时长 + 描述)。",
|
|
7804
|
-
example: "echopai payment plans"
|
|
7805
|
-
},
|
|
7806
7530
|
quote: {
|
|
7807
|
-
summary: "
|
|
7808
|
-
description: "
|
|
7531
|
+
summary: "Get real-time quotes for one or more securities.",
|
|
7532
|
+
description: "Returns real-time quotes for one or more A-share securities (canonical codes, e.g. `SSE:600519`): last price, volume, percent change, and bid/ask. Up to 200 codes per call. The response carries a `session` label (`pre_open` / `auction` / `open` / `break` / `closed`) and, outside continuous trading, an explanatory `note`: during 9:00–9:14 pre-open the previous session's snapshot is returned; during the 9:15–9:29 call auction, prices are indicative auction match prices. Rows whose feed has stopped updating (suspension / feed drop) keep their last snapshot and are flagged `stale: true` with `stale_since`. Requires a `quote:l1`, `quote:l2`, or `quote:delayed` scope.",
|
|
7809
7533
|
example: "echopai quote --codes ['SSE:600519', 'SZSE:000001']"
|
|
7810
7534
|
},
|
|
7811
7535
|
"quote.scan": {
|
|
7812
|
-
summary: "
|
|
7813
|
-
description:
|
|
7536
|
+
summary: "Snapshot every A-share real-time quote in one call.",
|
|
7537
|
+
description: "Returns a real-time quote for every A-share in a single call — use it for full-market scans or to discover a universe of interest when you do not yet know which codes to query. Filter with `exchange=SSE|SZSE|BSE` to narrow to one exchange. The payload is large (~3 MB, ~5,800 instruments), so pair it with `--fields`, `--jq`, or `--max-bytes` to trim it. The response carries a `session` label (`pre_open` / `auction` / `open` / `break` / `closed`) plus an explanatory `note` outside continuous trading: during 9:00–9:14 pre-open the previous session's snapshot is returned; during the 9:15–9:29 call auction, prices are indicative auction match prices. Instruments whose feed has stopped updating (suspension / feed drop) are excluded from the default scan; pass `include=all` to keep them, flagged with `stale: true` and `stale_since`. Each item also includes `main_net_in` (current-day cumulative net main-capital inflow in CNY, which may be negative) and a companion `main_net_in_stale` flag (true when served from the last-close fallback). Requires a `quote:l1`, `quote:l2`, or `quote:delayed` scope.",
|
|
7814
7538
|
example: "echopai quote scan"
|
|
7815
7539
|
},
|
|
7816
7540
|
"search.semantic": {
|
|
7817
|
-
summary: "
|
|
7818
|
-
description:
|
|
7819
|
-
+ DashScope embedding)、trigram 模糊、ILIKE 精确四路召回,RRF 融合后用 reranker
|
|
7820
|
-
精排,叠时间衰减 + views 加权(views 主源优先)。
|
|
7821
|
-
|
|
7822
|
-
- 搜"锂电池"会带出新能源产业链(正极/负极/碳酸锂/宁德时代…)
|
|
7823
|
-
- 搜"芯片"会带出存储芯片/洁净室/晶圆代工…
|
|
7824
|
-
- mode=exact 兼容老 ILIKE 行为,仅在精确关键词命中时返回。
|
|
7825
|
-
`,
|
|
7541
|
+
summary: "Semantic search across news and analyst views.",
|
|
7542
|
+
description: 'Hybrid semantic search across news and analyst views that generalizes beyond exact keywords. It combines exact entity matching (security codes, analysts), semantic (embedding-based) recall, and fuzzy matching, then fuses and re-ranks results with time decay and a weighting toward analyst views as the primary source. For example, searching "锂电池" surfaces the broader new-energy supply chain (cathode/anode materials, lithium carbonate, leading battery makers). Pass `mode=exact` for legacy exact-keyword behavior.',
|
|
7826
7543
|
example: "echopai search semantic --q 锂电池"
|
|
7827
7544
|
},
|
|
7828
|
-
"securities.industry": {
|
|
7829
|
-
summary: "TDX + 申万 industry classification for one A-share security",
|
|
7830
|
-
description: `返回该股票的 TDX 自定义行业代码(T1001 食品饮料等)与申万行业三级代码
|
|
7831
|
-
L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
7832
|
-
|
|
7833
|
-
用法:
|
|
7834
|
-
- 股票详情页"申万行业:白酒 / 食品饮料"标签
|
|
7835
|
-
- 筛选器交叉过滤:行业 + ROE/营收增长率
|
|
7836
|
-
- AI agent \`find_peers(code)\` 用申万二级行业找同业
|
|
7837
|
-
`,
|
|
7838
|
-
example: "echopai securities industry --code SSE:600519"
|
|
7839
|
-
},
|
|
7840
7545
|
"semantic.find": {
|
|
7841
|
-
summary: "
|
|
7842
|
-
description: "
|
|
7546
|
+
summary: "Resolve A-share securities by name, code, or pinyin.",
|
|
7547
|
+
description: "Finds A-share securities matching a Chinese name, a code (e.g. `600519`), or pinyin initials (e.g. `gzmt`). Use it to turn a free-form description into canonical codes (e.g. `SSE:600519`).",
|
|
7843
7548
|
example: "echopai semantic find --query 贵州茅台"
|
|
7844
7549
|
},
|
|
7845
7550
|
"sentiment.breadth": {
|
|
7846
|
-
summary: "
|
|
7847
|
-
description: "
|
|
7551
|
+
summary: "Get the intraday market-breadth time series.",
|
|
7552
|
+
description: "Returns the intraday market-breadth time series for one trading day. Omit `trade_date` for today (returns empty before 9:00); pass `YYYY-MM-DD` for any historical trading day (sparse minutes around the lunch break are excluded; up to 241 rows per day). Requires the `sentiment:read` scope.",
|
|
7848
7553
|
example: "echopai sentiment breadth"
|
|
7849
7554
|
},
|
|
7850
7555
|
"sentiment.overview": {
|
|
7851
|
-
summary: "
|
|
7852
|
-
description: "
|
|
7556
|
+
summary: "Get aggregate market sentiment indicators.",
|
|
7557
|
+
description: "Returns an aggregate sentiment snapshot for the latest minute of one trading day: limit-up/down counts, breadth, divergence index, and moving-average / 52-week breadth. Omit `trade_date` for today's real-time snapshot (returns an empty structure before 9:00); pass `YYYY-MM-DD` for any historical day (the day's final aggregated minute). Requires the `sentiment:read` scope.",
|
|
7853
7558
|
example: "echopai sentiment overview --scope main_board"
|
|
7854
7559
|
},
|
|
7855
7560
|
"sentiment.pct-distribution": {
|
|
7856
|
-
summary: "
|
|
7857
|
-
description: "
|
|
7561
|
+
summary: "Get the intraday percent-change distribution.",
|
|
7562
|
+
description: "Returns the distribution of intraday percent change across the full A-share universe, bucketed (≤-10% / -9% / ... / +10% / limit-up), for visualizing market breadth.",
|
|
7858
7563
|
example: "echopai sentiment pct-distribution"
|
|
7859
7564
|
},
|
|
7860
7565
|
"sentiment.turnover": {
|
|
7861
|
-
summary: "
|
|
7862
|
-
description: "
|
|
7566
|
+
summary: "Get the intraday turnover time series.",
|
|
7567
|
+
description: "Returns the intraday turnover time series across one or more trading days. Omit `trade_date` for today (returns empty before 9:00); pass `YYYY-MM-DD` for that day plus the preceding `days-1` days. The response includes headline fields `current_turnover`, `predicted_total`, and `delta_vs_yesterday`. Requires the `sentiment:read` scope.",
|
|
7863
7568
|
example: "echopai sentiment turnover"
|
|
7864
7569
|
},
|
|
7865
7570
|
"stocks.hot": {
|
|
7866
|
-
summary: "
|
|
7867
|
-
description: "
|
|
7571
|
+
summary: "Get today's hot-stock leaderboard.",
|
|
7572
|
+
description: "Returns today's most-popular A-share stocks, ranked by a composite score of searches, follows, and comments.",
|
|
7868
7573
|
example: "echopai stocks hot"
|
|
7869
7574
|
},
|
|
7870
7575
|
"stocks.social-hot": {
|
|
7871
|
-
summary: "
|
|
7872
|
-
description: "
|
|
7576
|
+
summary: "Get cross-platform social-hot stocks.",
|
|
7577
|
+
description: "Returns a leaderboard of A-share stocks aggregated by social-media mentions across multiple platforms, ranked by mention volume and sentiment score.",
|
|
7873
7578
|
example: "echopai stocks social-hot"
|
|
7874
7579
|
},
|
|
7875
7580
|
"views.document": {
|
|
7876
|
-
summary: "
|
|
7877
|
-
description: "
|
|
7581
|
+
summary: "Get the full research-report text behind a view.",
|
|
7582
|
+
description: "Returns the full parsed text of the research report behind one view. Available only for views with `full_text_available=true`. Large documents default to `format=outline`, returning a heading-only table of contents plus total character count; use `format=full` with `offset` / `max_chars` to page through the body via the `next_offset` cursor. Requires the `views:read` scope.",
|
|
7878
7583
|
example: "echopai views document VALUE"
|
|
7879
7584
|
},
|
|
7880
7585
|
"views.feed": {
|
|
7881
|
-
summary: "List analyst views",
|
|
7882
|
-
description: "
|
|
7586
|
+
summary: "List analyst views.",
|
|
7587
|
+
description: "Returns a stream of analyst views, sell-side research, and long-form opinion. Filter by institution, analyst, security, or recency (`hours`). Partner/agent callers receive `fields=compact` by default (id, ai_summary, attribution, tagged securities, first ~300 chars of content); pass `fields=full` for complete content. Requires the `views:read` scope.",
|
|
7883
7588
|
example: "echopai views feed"
|
|
7884
7589
|
},
|
|
7885
7590
|
"views.get": {
|
|
7886
|
-
summary: "
|
|
7887
|
-
description: "
|
|
7591
|
+
summary: "Get a single analyst view.",
|
|
7592
|
+
description: "Returns the full content of one analyst view: body, attached images, tagged securities, and AI summary.",
|
|
7888
7593
|
example: "echopai views get VALUE"
|
|
7889
7594
|
},
|
|
7890
7595
|
"views.recent": {
|
|
7891
|
-
summary: "
|
|
7892
|
-
description: "
|
|
7596
|
+
summary: "List recent analyst views.",
|
|
7597
|
+
description: "Returns recent broker / analyst views (research notes, price targets, ratings). Filter by analyst, institution, or a specific security. Requires the `views:read` scope.",
|
|
7893
7598
|
example: "echopai views recent --security HK:00700"
|
|
7894
7599
|
}
|
|
7895
7600
|
};
|
|
@@ -7898,7 +7603,7 @@ L1/L2/L3(X5001 食品饮料 / X500102 白酒 等)。
|
|
|
7898
7603
|
function verbToRecord(spec) {
|
|
7899
7604
|
let inputSchema;
|
|
7900
7605
|
try {
|
|
7901
|
-
inputSchema =
|
|
7606
|
+
inputSchema = z18.toJSONSchema(z18.object(spec.inputSchema));
|
|
7902
7607
|
} catch {
|
|
7903
7608
|
inputSchema = {
|
|
7904
7609
|
type: "object",
|
|
@@ -8410,26 +8115,27 @@ try {
|
|
|
8410
8115
|
}
|
|
8411
8116
|
} catch {}
|
|
8412
8117
|
var program = new Command31;
|
|
8413
|
-
program.name("echopai").description(`
|
|
8414
|
-
` + `and
|
|
8118
|
+
program.name("echopai").description(`Command-line access to the EchoPai market-data platform: quotes, news,
|
|
8119
|
+
` + `analyst research, fundamentals, and sentiment.
|
|
8415
8120
|
|
|
8416
|
-
` + `
|
|
8417
|
-
` + `codes (0 success / 1 user error / 2 service
|
|
8418
|
-
` +
|
|
8419
|
-
|
|
8420
|
-
|
|
8421
|
-
` + `Curated verbs: echopai <verb>
|
|
8422
|
-
` + `
|
|
8423
|
-
` + `Market
|
|
8424
|
-
` + `
|
|
8425
|
-
` + `
|
|
8426
|
-
` + `
|
|
8427
|
-
` + `
|
|
8121
|
+
` + `Machine-readable by design — a JSON envelope on stdout, JSON errors on
|
|
8122
|
+
` + `stderr, and three-state exit codes (0 success / 1 user error / 2 service
|
|
8123
|
+
` + `error) — built for AI agents and scripts. Authenticate with the
|
|
8124
|
+
` + "ECHOPAI_KEY environment variable or `echopai login`.").version(CLI_VERSION, "-V, --version").addOption(new Option23("--debug", "Print HTTP wire trace to stderr (Bearer redacted)")).addOption(new Option23("--raw", "Pass through raw response body (skip envelope wrap)")).addOption(new Option23("--jq <jmespath>", "Filter or transform output with a JMESPath expression.")).addOption(new Option23("--fields <a,b,c>", "Keep only listed top-level fields per item")).addOption(new Option23("--max-bytes <n>", "Truncate serialized envelope to N bytes (sets meta.truncated)")).addOption(new Option23("--yes", "Confirm a write op in non-TTY mode (required for sideEffect=write in agents / CI)")).addOption(new Option23("--dry-run", "Send X-Dry-Run:1 on write ops where the server advertises dry-run support")).addHelpText("after", `
|
|
8125
|
+
Authentication: ECHOPAI_KEY=<eps_live_...> echopai <command>
|
|
8126
|
+
` + `Curated verbs: echopai <verb> # task-level commands (recommended)
|
|
8127
|
+
` + `Raw operations: echopai raw <noun> <verb> # low-level access to every API operation
|
|
8128
|
+
` + `Market session: echopai market status # trading phase + next trading day
|
|
8129
|
+
` + `Market movers: echopai market movers --sort pct --top 20 # ranked movers (pct / speed / amount / turnover / total_mv)
|
|
8130
|
+
` + `Announcements: echopai announcements stock --code SSE:600519 # listed-company disclosures
|
|
8131
|
+
` + `Concepts: echopai concepts alerts # active concept-board alerts
|
|
8132
|
+
` + `Limit-up: echopai limit-up summary # limit-up / failed-board / consecutive-board ladder
|
|
8133
|
+
` + `Fundamentals: echopai financials quote-snapshot --code SSE:600519 # 14-field valuation snapshot
|
|
8428
8134
|
` + `Capability: echopai whoami | echopai doctor
|
|
8429
|
-
` + `Schema dump: echopai schema export
|
|
8135
|
+
` + `Schema dump: echopai schema export # machine-readable command surface for agents
|
|
8430
8136
|
` + `Profile: echopai config profile add prod --base-url https://api.echopai.com
|
|
8431
|
-
` + `Self-update: echopai upgrade [--check] [--exec]
|
|
8432
|
-
` + `MCP: echopai mcp install
|
|
8137
|
+
` + `Self-update: echopai upgrade [--check] [--exec]
|
|
8138
|
+
` + `MCP: echopai mcp install # register with Claude Code
|
|
8433
8139
|
`);
|
|
8434
8140
|
var dispatch = async (op, args) => {
|
|
8435
8141
|
const globals = program.opts();
|
|
@@ -8458,7 +8164,7 @@ function applyAiFirstHooks(cmd) {
|
|
|
8458
8164
|
for (const sub of cmd.commands)
|
|
8459
8165
|
applyAiFirstHooks(sub);
|
|
8460
8166
|
}
|
|
8461
|
-
var rawCmd = new Command31("raw").description("
|
|
8167
|
+
var rawCmd = new Command31("raw").description("Low-level access to every API operation (advanced; bypasses the curated verbs).");
|
|
8462
8168
|
buildCommandTree(rawCmd, dispatch);
|
|
8463
8169
|
rawCmd.addCommand(buildRawCallCommand());
|
|
8464
8170
|
program.addCommand(rawCmd);
|