@alphafox/cli 0.3.8 → 0.3.10

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.
@@ -14,11 +14,12 @@ const client_1 = require("../http/client");
14
14
  const store_1 = require("../keychain/store");
15
15
  const confirmation_1 = require("../safety/confirmation");
16
16
  const version_1 = require("../version");
17
- const run_command_1 = require("../engine-backtest/run-command");
18
- const run_command_2 = require("../resolve-symbols/run-command");
19
- const run_command_3 = require("../skills/run-command");
17
+ const run_command_1 = require("../cache/run-command");
18
+ const run_command_2 = require("../engine-backtest/run-command");
19
+ const run_command_3 = require("../resolve-symbols/run-command");
20
+ const run_command_4 = require("../skills/run-command");
20
21
  const notify_1 = require("../update/notify");
21
- const run_command_4 = require("../update/run-command");
22
+ const run_command_5 = require("../update/run-command");
22
23
  const validate_body_1 = require("../catalog/validate-body");
23
24
  const types_1 = require("../install/types");
24
25
  const wizard_1 = require("../install/wizard");
@@ -102,6 +103,7 @@ async function runCli(argv, env = process.env) {
102
103
  "alphafox api METHOD PATH [--body JSON|--config @file]",
103
104
  "alphafox engine-backtest run --experiment <uuid> --definition <id> --config @file --exchange <id> --range FROM..TO --initial-equity N",
104
105
  "alphafox engine-backtest sweep --experiment <uuid> --definition <id> --config @file --axes @file --exchange <id> --range FROM..TO --initial-equity N --no-persist",
106
+ "alphafox cache status|clean [--tape|--runtime|--all]",
105
107
  "alphafox resolve-symbols <query...> [--exchange binance] [--asset-class equity_perp]",
106
108
  "alphafox <domain> <resource> <action> [flags]",
107
109
  ],
@@ -120,7 +122,8 @@ async function runCli(argv, env = process.env) {
120
122
  if (cmd !== "version" &&
121
123
  cmd !== "install" &&
122
124
  cmd !== "update" &&
123
- cmd !== "skills") {
125
+ cmd !== "skills" &&
126
+ cmd !== "cache") {
124
127
  assertCatalogCompatible();
125
128
  }
126
129
  switch (cmd) {
@@ -129,9 +132,11 @@ async function runCli(argv, env = process.env) {
129
132
  case "install":
130
133
  return await cmdInstall(args, flags, env);
131
134
  case "update":
132
- return await (0, run_command_4.cmdUpdate)(args, flags, env);
135
+ return await (0, run_command_5.cmdUpdate)(args, flags, env);
133
136
  case "skills":
134
- return await (0, run_command_3.cmdSkills)(args, flags, env);
137
+ return await (0, run_command_4.cmdSkills)(args, flags, env);
138
+ case "cache":
139
+ return await (0, run_command_1.cmdCache)(args, flags, env);
135
140
  case "doctor":
136
141
  return cmdDoctor(flags, env);
137
142
  case "whoami":
@@ -154,7 +159,7 @@ async function runCli(argv, env = process.env) {
154
159
  sub === "help" ||
155
160
  sub === "--help" ||
156
161
  sub === "-h") {
157
- return await (0, run_command_1.cmdEngineBacktest)(args, flags, env);
162
+ return await (0, run_command_2.cmdEngineBacktest)(args, flags, env);
158
163
  }
159
164
  // Hyphen built-in owns `run` and `sweep`. Underscore/hyphen catalog CRUD
160
165
  // (engine_backtest.experiments.*) still goes through the typed tree.
@@ -162,7 +167,7 @@ async function runCli(argv, env = process.env) {
162
167
  }
163
168
  case "resolve-symbols":
164
169
  case "resolve-symbol":
165
- return await (0, run_command_2.cmdResolveSymbols)(args, flags, env);
170
+ return await (0, run_command_3.cmdResolveSymbols)(args, flags, env);
166
171
  default:
167
172
  return await cmdTyped(cmd, args, flags, env);
168
173
  }
@@ -14,6 +14,7 @@ const load_config_1 = require("./load-config");
14
14
  const parse_args_1 = require("./parse-args");
15
15
  const sweep_command_1 = require("./sweep-command");
16
16
  const persist_1 = require("./persist");
17
+ const paths_1 = require("../cache/paths");
17
18
  const replay_timeframe_1 = require("./replay-timeframe");
18
19
  const resolve_packages_1 = require("./resolve-packages");
19
20
  var load_config_2 = require("./load-config");
@@ -316,6 +317,7 @@ async function executeEngineBacktestRun(args, flags, env = process.env, deps = {
316
317
  fromMs: args.range.fromMs,
317
318
  toMs: args.range.toMs,
318
319
  dataQualityMode: args.dataQualityMode,
320
+ cacheDir: (0, paths_1.resolveTapeCacheDir)(env),
319
321
  onProgress: (progress) => {
320
322
  emitProgress(flags, writeLine, progress.stage || "tape", progress.fraction, progress.detail);
321
323
  },
@@ -7,6 +7,7 @@ exports.executeEngineBacktestSweep = executeEngineBacktestSweep;
7
7
  const node_crypto_1 = require("node:crypto");
8
8
  const profiles_1 = require("../config/profiles");
9
9
  const client_1 = require("../http/client");
10
+ const paths_1 = require("../cache/paths");
10
11
  const store_1 = require("../keychain/store");
11
12
  const errors_1 = require("./errors");
12
13
  const load_config_1 = require("./load-config");
@@ -189,6 +190,7 @@ async function executeEngineBacktestSweep(args, flags, env = process.env, deps =
189
190
  fromMs: args.range.fromMs,
190
191
  toMs: args.range.toMs,
191
192
  dataQualityMode: args.dataQualityMode,
193
+ cacheDir: (0, paths_1.resolveTapeCacheDir)(env),
192
194
  onProgress: (progress) => {
193
195
  emitProgress(flags, writeLine, progress.stage || "tape", progress.fraction, progress.detail);
194
196
  },
@@ -238,6 +238,7 @@ export interface BacktestRunnerModule {
238
238
  readonly fromMs: number;
239
239
  readonly toMs: number;
240
240
  readonly dataQualityMode?: DataQualityMode;
241
+ readonly cacheDir?: string;
241
242
  readonly onProgress?: (progress: TapeLoadProgress) => void;
242
243
  }, options?: unknown): Promise<TapeLoadResult>;
243
244
  assembleScenario(input: {
@@ -1,141 +1,153 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "packageName": "@alphafox/cli",
4
- "packageVersion": "0.3.8",
4
+ "packageVersion": "0.3.10",
5
5
  "contractVersion": "2026-08-13",
6
- "bundleHash": "cd05f4eb6f9e1a7c9188ac5770196698c6f2c9ff6aaebfbfbaba3581ef08d226",
6
+ "bundleHash": "e03966174d892d1205e0f4a5ec69c11d7cd78e9f5bd2f95fc3e145b7dfea14cd",
7
7
  "skills": [
8
8
  {
9
9
  "name": "alphafox",
10
- "version": "0.3.8",
10
+ "version": "0.3.10",
11
11
  "files": [
12
12
  {
13
13
  "path": "SKILL.md",
14
- "sha256": "e8eadf96f36f6aa124b36d15a912465e839389e5228dbf9dfd9ad2f1ec86f65a",
15
- "size": 3553
14
+ "sha256": "58466ff1f9d42d6c64b1a4b2d52bafd40857dd7e0ca928f987fc926c358bd850",
15
+ "size": 4407
16
16
  }
17
17
  ],
18
- "hash": "fb41a55fcd363231cb69e30e4c0fe7b1ad2e17b12e2bb90cfda7d6e9ccd2f02c"
18
+ "hash": "363bf0b3746b8cd8b291956b58dd9ac3e001bc1bfb80f0fa9c471aec4bf0021d"
19
19
  },
20
20
  {
21
21
  "name": "alphafox-account",
22
- "version": "0.3.8",
22
+ "version": "0.3.10",
23
23
  "files": [
24
24
  {
25
25
  "path": "SKILL.md",
26
- "sha256": "9925573bf644b998ea683df7a20276a835d33cb83b0548ee0d1c43429ad99582",
27
- "size": 783
26
+ "sha256": "4fcc7608817c900055dd605e0e71cd5b05e0945516701d0a281ebefb0407fb7b",
27
+ "size": 784
28
28
  }
29
29
  ],
30
- "hash": "934bcd76d1bea875324673ffcc3d1c52e3f4065f776c4958ffc230cf911bac21"
30
+ "hash": "273fdb4dd81103fc214b85ab7d59fb9dd65ebf2ec6d5d0d889837573bd8e3dae"
31
31
  },
32
32
  {
33
33
  "name": "alphafox-admin",
34
- "version": "0.3.8",
34
+ "version": "0.3.10",
35
35
  "files": [
36
36
  {
37
37
  "path": "SKILL.md",
38
- "sha256": "e9ae0b433cead54e9c284f0ea8859dd9e96123f842788938319404b96bc085e7",
39
- "size": 787
38
+ "sha256": "0639573e3d59f42d3d718bdf07d719b01d802cbbdc04806c14882ebf8cd7c081",
39
+ "size": 788
40
40
  }
41
41
  ],
42
- "hash": "1346e798f18582c16cfbb887667272406f170e775d3027131d3d88e1f1a656e3"
42
+ "hash": "bcd9d41096e65472eebc0981cc9f614c755f28ae307dffdb15117ad8e22c954c"
43
43
  },
44
44
  {
45
45
  "name": "alphafox-auth",
46
- "version": "0.3.8",
46
+ "version": "0.3.10",
47
47
  "files": [
48
48
  {
49
49
  "path": "SKILL.md",
50
- "sha256": "8ec9f081d9a1d40606ac7c18cba5dae9f1b6144ddc0079005b16af54be8f2f46",
51
- "size": 2370
50
+ "sha256": "d4edec17dd89e9e2e5d1759657837456f60d0b062d0a332334d9e6df6bfe003e",
51
+ "size": 2371
52
52
  }
53
53
  ],
54
- "hash": "854910a6792aa6d0a8b9cd796afb41753a34cef79df95c5b50de432f03a4e67a"
54
+ "hash": "01c80f4fa33736e85b845576e5d026e7ec32869a8c0f806119625d44e43fcbaa"
55
+ },
56
+ {
57
+ "name": "alphafox-cache",
58
+ "version": "0.3.10",
59
+ "files": [
60
+ {
61
+ "path": "SKILL.md",
62
+ "sha256": "c7f36174e5bb1ac97ca55e89b6720863d3d05a52a522ff5498a4c5ea4a31adaa",
63
+ "size": 1530
64
+ }
65
+ ],
66
+ "hash": "a5a68c82de33aa8e09b12a65de1c45c522490d1b807c34a9616792cc71a13350"
55
67
  },
56
68
  {
57
69
  "name": "alphafox-engine-backtest",
58
- "version": "0.3.8",
70
+ "version": "0.3.10",
59
71
  "files": [
60
72
  {
61
73
  "path": "SKILL.md",
62
- "sha256": "e5f37b8541c510a27f84cbf9eea7524efe0b8f9c60c4faf17521b6cac298f92b",
63
- "size": 7584
74
+ "sha256": "dbcb6dc047150bdf3988da112691868787be4a51bda95e60c63628269b06a8d7",
75
+ "size": 7803
64
76
  }
65
77
  ],
66
- "hash": "efb614f145763f514c33d02e112657bd42868cc746f13dbcb3cceaa0ecb770e4"
78
+ "hash": "1e85862e3ea104968061a0d778b836a6475b1d676dfbbb80a074851cd4e386fb"
67
79
  },
68
80
  {
69
81
  "name": "alphafox-exchange",
70
- "version": "0.3.8",
82
+ "version": "0.3.10",
71
83
  "files": [
72
84
  {
73
85
  "path": "SKILL.md",
74
- "sha256": "118141754916741f4f8b449cf307a89cdfa11f234302726ba4d6b58e396327b5",
75
- "size": 743
86
+ "sha256": "100f74f3240d86e73531a981585c9a236d3d5fd3ea31ecb54a74074d4e256403",
87
+ "size": 744
76
88
  }
77
89
  ],
78
- "hash": "3933f12a2d8c55db465d4a11cf1f7d40f90fff81b3931f398e2fe3bcaf064d62"
90
+ "hash": "9230a196316900e2cf6bd15659d2bf47f5332d855663f4dd116744139cfcf968"
79
91
  },
80
92
  {
81
93
  "name": "alphafox-market",
82
- "version": "0.3.8",
94
+ "version": "0.3.10",
83
95
  "files": [
84
96
  {
85
97
  "path": "SKILL.md",
86
- "sha256": "0e77dcc697fe60f742e1075986685db5018d9d659a4d8f44f9cc343117c1c74b",
87
- "size": 3078
98
+ "sha256": "e750c23aaad020221a6cfdf2b273886c8367de63ca68df6a95cb31492c447f0d",
99
+ "size": 3079
88
100
  }
89
101
  ],
90
- "hash": "710c45c6124583d3fa9c9584f67bbc665bad35c9e6d1294c7416f493b8a6b184"
102
+ "hash": "34283bcd2403e671ba5dcd4da7d3ad65f73a46ca3a5d29d28c3464038dfb074c"
91
103
  },
92
104
  {
93
105
  "name": "alphafox-notification",
94
- "version": "0.3.8",
106
+ "version": "0.3.10",
95
107
  "files": [
96
108
  {
97
109
  "path": "SKILL.md",
98
- "sha256": "712aa6a4de8090bb7ee57373d35dd95c62bad7a24e443747afa4f11fb6e79b68",
99
- "size": 698
110
+ "sha256": "4d6e705ff6aff33af729bca184dcb716cd97d31b4fe188173b07423eba0d94d4",
111
+ "size": 699
100
112
  }
101
113
  ],
102
- "hash": "5f2feef0e17912a593bafae0961f983e3f781d12800e4808c136004897321ab2"
114
+ "hash": "a36312725ffa86ed9e629b056375b68ae6955d56a304c5895e4ab24666a53763"
103
115
  },
104
116
  {
105
117
  "name": "alphafox-shared",
106
- "version": "0.3.8",
118
+ "version": "0.3.10",
107
119
  "files": [
108
120
  {
109
121
  "path": "SKILL.md",
110
- "sha256": "c6bab01f9c8369f9c2a29eebf7b46462887f14d3bec7ad00e2a159d395346508",
111
- "size": 5385
122
+ "sha256": "4019aba3820aa1cf16dcb49202f251e4074829a130a7608caf6c67c3118a799c",
123
+ "size": 5386
112
124
  }
113
125
  ],
114
- "hash": "2b78fe080877af19b659964a8c965720e5ab731dd157ced10d2ee598b8c574a0"
126
+ "hash": "ae7dbd98f00f8f6162d5dc77bd35ca13303895f7d6c91d910af1f46f03d2869e"
115
127
  },
116
128
  {
117
129
  "name": "alphafox-strategy",
118
- "version": "0.3.8",
130
+ "version": "0.3.10",
119
131
  "files": [
120
132
  {
121
133
  "path": "SKILL.md",
122
- "sha256": "03f1d1c6d048d7b0a23d725c6585d1d019445579be9779dc93095ebafb3fcf5a",
123
- "size": 1826
134
+ "sha256": "85c78855f0a312f5093642668606197cc68569e9203f5b85a6e9c4bd3b9c9c21",
135
+ "size": 1827
124
136
  }
125
137
  ],
126
- "hash": "ebf375c6eeaf13c971a3090d05beda7037f253325ee2236c35b26ad540922827"
138
+ "hash": "cb79e63d42a2559d2ec69b684c7d13d3351b49e117ca3256f462f0f04ba7d657"
127
139
  },
128
140
  {
129
141
  "name": "alphafox-trading",
130
- "version": "0.3.8",
142
+ "version": "0.3.10",
131
143
  "files": [
132
144
  {
133
145
  "path": "SKILL.md",
134
- "sha256": "4b597f23ff6c8ce384e8fd56fab73c6128d373741285bac6df0b061e7ee50242",
135
- "size": 3122
146
+ "sha256": "b580088309ddaeb0b460b572c9861393fe8d9b1129fca2f9dd2e9caa4b568368",
147
+ "size": 3123
136
148
  }
137
149
  ],
138
- "hash": "d7e818482ec3ba9aeab50af72e72f990288f0e2e6714e1227cba441db05fa75a"
150
+ "hash": "c215ba2c61b5d4487046bb7f56145eabdc942c70c6c36f2d79cc2d7da887463f"
139
151
  }
140
152
  ]
141
153
  }
package/dist/version.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export declare const CLI_NAME = "alphafox";
2
2
  export declare const CLI_PACKAGE = "@alphafox/cli";
3
- export declare const CLI_VERSION = "0.3.8";
3
+ export declare const CLI_VERSION = "0.3.10";
4
4
  export { CATALOG_VERSION as CLI_CONTRACT_VERSION } from "./catalog/operations";
package/dist/version.js CHANGED
@@ -3,6 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CLI_CONTRACT_VERSION = exports.CLI_VERSION = exports.CLI_PACKAGE = exports.CLI_NAME = void 0;
4
4
  exports.CLI_NAME = "alphafox";
5
5
  exports.CLI_PACKAGE = "@alphafox/cli";
6
- exports.CLI_VERSION = "0.3.8";
6
+ exports.CLI_VERSION = "0.3.10";
7
7
  var operations_1 = require("./catalog/operations");
8
8
  Object.defineProperty(exports, "CLI_CONTRACT_VERSION", { enumerable: true, get: function () { return operations_1.CATALOG_VERSION; } });
@@ -10,13 +10,15 @@ Staging CLI issuer: `https://staging.alphafox.app`. Test login (staging-only, ga
10
10
  2. Device Flow split (`--no-wait` + `--device-code`)
11
11
  3. `whoami` / `auth status --verify`
12
12
  4. Readonly: strategy definitions, connectors, traders
13
- 5. Write: create chat with idempotency
14
- 6. Backtest create → watch stream → cancel
13
+ 5. ~~Write: create chat with idempotency~~ **historical** — chat is not a CLI surface; do not use `chats.create` as the trader-create path
14
+ 6. ~~Backtest create → watch stream → cancel~~ **historical** — web `/api/v1/backtests` is not a CLI surface; use `engine-backtest`
15
15
  7. High-risk without `--yes` → exit 10
16
16
  8. Logout / revoke
17
17
  9. Cross-env token rejection (prod token on staging)
18
18
 
19
- ## Evidence (2026-08-13) — vertical slice pass
19
+ ## Evidence (2026-08-13) — vertical slice pass (historical chat / web-backtest slice)
20
+
21
+ The chat and `POST /api/v1/backtests` steps below are a **historical** facade record. They are not the CLI trader-create path. Current create is Engine `trading.traders.create` (`strategyDefinitionId` + `config`). Do not treat this section as a playbook.
20
22
 
21
23
  Anonymous `GET https://staging.alphafox.app/api/v1/meta` → **HTTP 200**, `environment=staging`, `contractVersion=2026-08-13`, `commitSha=65d1f816007adc7acc09db5e86671931737e0379`, `x-request-id=66511bcf-dda9-4974-9378-3aacd8d938ff`. No 302 to `vercel.com/sso-api`. Vercel Authentication is disabled for the whole `alphafox-web` project (Preview `*.vercel.app` is also public; accepted).
22
24
 
@@ -66,7 +68,7 @@ Reused staging Device Flow session `userId=019f3073-307f-76e9-adf1-0203af9ab22b`
66
68
  - **Backtest vertical slice:** cannot `create → stream → cancel` until a chat has an integer `strategyId`, and until the facade body matches contracts (`backtestSettings`) or the catalog is updated to `{chatId, strategyId}`.
67
69
  - Parent Feishu task and t101364 (production publish / npm `latest` / production OAuth) stay **todo**. Do not merge web PR 448 to production `main` from this evidence.
68
70
 
69
- ## Evidence (2026-08-13) — gapfix retest (idempotency + backtests.create)
71
+ ## Evidence (2026-08-13) — gapfix retest (historical; idempotency + backtests.create)
70
72
 
71
73
  Anonymous `GET https://staging.alphafox.app/api/v1/meta` → **HTTP 200**, `environment=staging`, `contractVersion=2026-08-13`, `commitSha=fba21ef4b2c3909c51a5a19e2d2a45b30d1d598c`, `x-request-id=8702a21b-a749-4007-82eb-76ca1dd0caaf`. No SSO redirect. Device Flow `test@local.com`: approve `requestId=77293035-ebfd-4b03-b0e1-0779dce81fdd`, token `requestId=9dcc28c1-c1cc-49fc-9435-687dfdb591c2`, `whoami` `userId=019f3073-307f-76e9-adf1-0203af9ab22b` `requestId=1473f107-d742-42eb-99e7-b60c6b583928`. CLI local `92c8610250b30e7881f79a2fde60b00fe50b4628`, catalog `contractsSha=d1f184e3d72581f155497978880d9ab3029ff858`. Staging llm-gateway image `0a10d8e3a1304b04eff2f21c503922a5b7c11491` (workflow `31683345740` failed after the container was healthy: `/opt/alphafox/images/alphafox-llm-gateway.env` permission denied). Do not merge web PR 448 to production `main`.
72
74
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alphafox/cli",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "description": "AlphaFox CLI — Agent/Human entry for the public Application API.",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-account
3
3
  description: Account, wallet, and subscription read paths.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Account / wallet
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-admin
3
3
  description: Admin-only operations reusing Web role authorization.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Admin
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox
3
- description: AlphaFox CLI entry router. Use for any AlphaFox request — install, update, login, whoami, 回测, engine backtest, strategy definitions, create/list/start/stop a running strategy (trader), ticker/标的 resolve (美股 or crypto), market data, exchange connectors, wallet, subscriptions, notifications, or admin. If a CLI command prints `[alphafox] update available`, ask the user「检测到新的版本,是否需要我帮你升级?」and only then run `alphafox update --format json --no-input`. Start here, then open the routed domain skill. Do not guess alphafox-engine-backtest vs alphafox-strategy vs alphafox-trading from memory.
4
- version: 0.3.8
3
+ description: AlphaFox CLI entry router. Use for any AlphaFox request — install, update, login, whoami, 回测, engine backtest, 清理回测缓存 / 历史数据, strategy definitions, create/list/start/stop a running strategy (trader), ticker/标的 resolve (美股 or crypto), market data, exchange connectors, wallet, subscriptions, notifications, or admin. If a CLI command prints `[alphafox] update available`, ask the user「检测到新的版本,是否需要我帮你升级?」and only then run `alphafox update --format json --no-input`. After a large backtest, if tape cache is large, ask「回测下载的历史数据比较大,要不要我帮你清理本地缓存?」then open `alphafox-cache`. Start here, then open the routed domain skill. Do not guess alphafox-engine-backtest vs alphafox-strategy vs alphafox-trading from memory.
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # AlphaFox
@@ -22,6 +22,7 @@ A **trader** is a running strategy instance (paper or live), not a person. Creat
22
22
  | Login, logout, whoami, profile, staging vs production | `alphafox-auth` |
23
23
  | Ticker / 标的 / 美股 / crypto / resolve a misspelled symbol | `alphafox-market` |
24
24
  | Engine WASM backtest, experiment, `engine-backtest run`, persist a local run | `alphafox-engine-backtest` |
25
+ | 清理回测缓存 / 历史 K 线占磁盘 / `alphafox cache` | `alphafox-cache` |
25
26
  | Strategy types / definitions / validate config (grid, dca, copy, …) | `alphafox-strategy` |
26
27
  | Create, list, start, or stop a running strategy (trader), including copy | `alphafox-trading` |
27
28
  | Exchange connectors | `alphafox-exchange` |
@@ -36,7 +37,7 @@ If several rows apply, load **all** of them (typical: `alphafox-shared` + `alpha
36
37
  The CLI may print this on **stderr** at most once every 24 hours:
37
38
 
38
39
  ```text
39
- [alphafox] update available: 0.3.7 -> 0.3.8. After the user confirms, run: alphafox update --format json --no-input,
40
+ [alphafox] update available: 0.3.9 -> 0.3.10. After the user confirms, run: alphafox update --format json --no-input,
40
41
  ```
41
42
 
42
43
  If you see that notice (or `updateAvailable: true` from `alphafox update --check`):
@@ -60,3 +61,13 @@ Do not install Skills from GitHub. Details and dry-run / check commands live in
60
61
  - Web `/api/v1/backtests` (`backtests.*`) is **not** a CLI surface. Do not call it via typed commands, `schema`, or `alphafox api`.
61
62
 
62
63
  Ambiguous “帮我回测” → `alphafox-engine-backtest`, after resolving symbols.
64
+
65
+ ## Large historical tape
66
+
67
+ `engine-backtest run|sweep` downloads closed OHLCV into the local tape cache. After a long-range or 1m backtest (or whenever the operator mentions disk / 缓存), read `alphafox-cache` and run `alphafox cache status --format json --no-input`.
68
+
69
+ If `data.tape.large` is true (tape ≥ `data.remindAfterBytes`):
70
+
71
+ 1. Ask the user: **回测下载的历史数据比较大,要不要我帮你清理本地缓存?**
72
+ 2. Wait for an explicit yes. Do not clean on your own.
73
+ 3. Follow `alphafox-cache` (`alphafox cache clean --dry-run`, then `--yes`).
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-shared
3
3
  description: Shared AlphaFox CLI rules for Agents — auth, profiles, envelopes, risk gates, and public operationIds only.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # AlphaFox shared Agent contract
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-auth
3
3
  description: Login, status, logout, whoami, and environment isolation for AlphaFox CLI.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Auth Skill
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: alphafox-cache
3
+ description: Inspect and clean local Engine backtest caches (downloaded OHLCV tape and wasm runtime). Use when the user asks to 清理缓存, free disk, or after a large historical backtest.
4
+ version: 0.3.10
5
+ ---
6
+
7
+ # Cache
8
+
9
+ Always `--format json --no-input`. Never `--token`. This is local disk only.
10
+
11
+ `engine-backtest run|sweep` writes closed OHLCV into the **tape** cache (`~/.alphafox/cache/engine-backtest`, or `ALPHAFOX_TAPE_CACHE_DIR`). The wasm / Node host lives under the **runtime** cache (`~/.cache/alphafox/engine-backtest/<hash>/`). Tape is the large historical download.
12
+
13
+ ## Status first
14
+
15
+ ```bash
16
+ alphafox cache status --format json --no-input
17
+ ```
18
+
19
+ Read `data.tape.bytes`, `data.tape.files`, `data.tape.large`, `data.remindAfterBytes`. `large` is true when tape bytes ≥ `remindAfterBytes` (512 MiB).
20
+
21
+ If `data.tape.large` is true, ask the user:
22
+
23
+ **回测下载的历史数据比较大,要不要我帮你清理本地缓存?**
24
+
25
+ Wait for an explicit yes. Do not clean on your own.
26
+
27
+ ## Clean
28
+
29
+ Default clean is **tape only** (historical bars). Runtime re-downloads on the next run; only add `--runtime` or `--all` when the operator asks.
30
+
31
+ ```bash
32
+ alphafox cache clean --dry-run --format json --no-input
33
+ alphafox cache clean --yes --format json --no-input
34
+ ```
35
+
36
+ `--yes` is required to delete. `--dry-run` reports what would be removed. After clean, `data.bytesFreed` is the space recovered.
37
+
38
+ Do not `rm` cache paths by hand. Do not delete `~/.config/alphafox` (config / skills state / keychain).
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-engine-backtest
3
3
  description: Local Engine WASM backtest (alphafox engine-backtest run|sweep) vs catalog experiment CRUD.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Engine Backtest
@@ -94,6 +94,7 @@ Owner isolation and 7-day expiry are enforced by the server. Applying a coordina
94
94
  2. `engine-backtest run` (reuse `--experiment` after the first create).
95
95
  3. Read `data.metrics` / `data.engineVersion` / `data.runId` / `data.experimentUrl`.
96
96
  4. Adjust parameters and run again. Do not invent a token flag if persist returns 401 — `alphafox auth login`.
97
+ 5. After a long-range or 1m run, follow `alphafox-cache`: `alphafox cache status`. If `data.tape.large` is true, ask **回测下载的历史数据比较大,要不要我帮你清理本地缓存?** and wait for yes.
97
98
 
98
99
  ## Safety
99
100
 
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-exchange
3
3
  description: Exchange connectors list and connection management via Public API.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Exchange connectors
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-market
3
3
  description: Market data and ticker resolution for US equity perps, RWAs, and crypto on the same perp catalog. Use when the user names 美股, NVDA, AAPL, BTC, or any 标的. Keep the operator's asset class via symbolMetadata — do not rewrite NVDA into a crypto coin.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Market
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-notification
3
3
  description: Notification channels and subscriptions.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Notification
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-strategy
3
3
  description: Strategy definitions — list types (grid, dca, copy, …) and validate config. Creating a running strategy is creating a trader; use alphafox-trading for that.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Strategy definitions
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: alphafox-trading
3
3
  description: Running strategies (traders) — create, list, start, and stop. A trader is a live or paper strategy instance (grid, dca, copy, …), not a person.
4
- version: 0.3.8
4
+ version: 0.3.10
5
5
  ---
6
6
 
7
7
  # Running strategies (traders)
@@ -288,6 +288,8 @@ export interface TapeLoadRequest {
288
288
  readonly signal?: AbortSignal;
289
289
  readonly onProgress?: (progress: TapeLoadProgress) => void;
290
290
  readonly nowMs?: number;
291
+ readonly cacheDir?: string;
292
+ readonly seriesConcurrency?: number;
291
293
  readonly ohlcvFetcher?: TapeOhlcvFetcher;
292
294
  readonly fundingFetcher?: TapeFundingFetcher;
293
295
  readonly marketsLoader?: () => Promise<TapeMarketsSnapshot>;
@@ -302,6 +304,8 @@ export interface TapeProxyOptions {
302
304
  export interface TapeLoadOptions extends TapeProxyOptions {
303
305
  readonly cache?: FileTapeCache | false | "disable";
304
306
  readonly cacheDir?: string;
307
+ /** Independent series fetches; default 4, hard cap 8. Pagination stays serial. */
308
+ readonly seriesConcurrency?: number;
305
309
  readonly nowMs?: number;
306
310
  readonly onProgress?: (progress: TapeLoadProgress) => void;
307
311
  readonly createExchange?: (
@@ -336,6 +340,17 @@ export interface TapeLoadResult {
336
340
  };
337
341
  }
338
342
 
343
+ export const DEFAULT_TAPE_SERIES_CONCURRENCY: 4;
344
+ export const MAX_TAPE_SERIES_CONCURRENCY: 8;
345
+
346
+ export function resolveTapeSeriesConcurrency(value?: number): number;
347
+
348
+ export function mapWithConcurrency<T, R>(
349
+ items: readonly T[],
350
+ concurrency: number,
351
+ worker: (item: T, index: number) => Promise<R>
352
+ ): Promise<R[]>;
353
+
339
354
  export function loadTape(
340
355
  request: TapeLoadRequest,
341
356
  options?: TapeLoadOptions
@@ -50,8 +50,12 @@ export {
50
50
  loadSeriesWithCache,
51
51
  } from "./lib/series.mjs";
52
52
  export {
53
+ DEFAULT_TAPE_SERIES_CONCURRENCY,
54
+ MAX_TAPE_SERIES_CONCURRENCY,
53
55
  loadTape,
56
+ mapWithConcurrency,
54
57
  resolveTapeCache,
58
+ resolveTapeSeriesConcurrency,
55
59
  effectiveTapeEndMs,
56
60
  inferFundingIntervals,
57
61
  classifyTapeSymbolsForPreflight,