create-tradejs 3.1.21 → 3.1.22-beta.238

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/README.md CHANGED
@@ -18,6 +18,47 @@ npx create-tradejs my-trading-project
18
18
 
19
19
  Docker with the Compose plugin and Node.js 20.19 or newer are required.
20
20
 
21
+ ## Codex strategy skills
22
+
23
+ Every generated project includes focused workflow skills in `.codex/skills`:
24
+
25
+ - `$strategy-candidate-report` — show the latest selected candidate;
26
+ - `$strategy-candidate-compare` — compare it with production;
27
+ - `$strategy-improvement-plan` — produce a causal improvement plan;
28
+ - `$strategy-improvement-research` — run a new bounded research lineage;
29
+ - `$strategy-period-revalidate` — recheck frozen candidates on new data;
30
+ - `$strategy-forward-start` — publish and start the latest eligible candidate
31
+ at `MAX_LOSS_VALUE=1`, or an explicitly named reproducible historical
32
+ candidate under a prospective-only operator authorization;
33
+ - `$strategy-forward-status` — inspect prospective live evidence;
34
+ - `$strategy-risk-scale` — change only `MAX_LOSS_VALUE` after an explicit
35
+ scaling request.
36
+
37
+ Invoke one skill with one strategy name, for example:
38
+
39
+ ```text
40
+ $strategy-forward-start MarketFlushReversal
41
+ ```
42
+
43
+ Forward start is an explicit live rollout request. It still requires an exact
44
+ deployment/account binding and a configured package publication and deployment
45
+ workflow; the scaffolder does not invent production credentials or hosting.
46
+ Operator-directed mode does not rewrite an old research verdict: it preserves
47
+ the original selection and contrary evidence and requires positive full-period
48
+ PnL, profit factor above 1, and checksum-verifiable configuration and charts.
49
+
50
+ The generated files include `.codex/tradejs-skill-bundle.json`, which binds the
51
+ installed skills to the canonical TradeJS bundle by SHA-256. To update only
52
+ that managed bundle in an existing project, use an explicitly selected
53
+ `create-tradejs` version:
54
+
55
+ ```bash
56
+ npx create-tradejs@<approved-version> --update-skills .
57
+ ```
58
+
59
+ The updater preserves unrelated custom skills and refuses to overwrite a
60
+ managed file that no longer matches its installed checksum.
61
+
21
62
  ## License
22
63
 
23
64
  The `create-tradejs` scaffolder remains MIT-licensed. Generated projects
package/dist/index.js CHANGED
@@ -35,16 +35,208 @@ __export(index_exports, {
35
35
  findAvailablePort: () => findAvailablePort,
36
36
  main: () => main,
37
37
  parseArgs: () => parseArgs,
38
- scaffoldProject: () => scaffoldProject
38
+ scaffoldProject: () => scaffoldProject,
39
+ stageCanonicalSkillBundle: () => stageCanonicalSkillBundle,
40
+ updateProjectSkills: () => updateProjectSkills
39
41
  });
40
42
  module.exports = __toCommonJS(index_exports);
41
43
  var import_node_child_process = require("child_process");
44
+ var import_node_crypto2 = require("crypto");
45
+ var import_node_fs2 = require("fs");
46
+ var import_node_net = __toESM(require("net"));
47
+ var import_node_path2 = __toESM(require("path"));
48
+
49
+ // src/skillBundle.ts
42
50
  var import_node_crypto = require("crypto");
43
51
  var import_node_fs = require("fs");
44
- var import_node_net = __toESM(require("net"));
45
52
  var import_node_path = __toESM(require("path"));
53
+ var PROJECT_SKILL_BUNDLE_MANIFEST = ".codex/tradejs-skill-bundle.json";
54
+ var PROJECT_SKILL_NAMES = [
55
+ "strategy-candidate-report",
56
+ "strategy-candidate-compare",
57
+ "strategy-improvement-plan",
58
+ "strategy-improvement-research",
59
+ "strategy-period-revalidate",
60
+ "strategy-forward-start",
61
+ "strategy-forward-status",
62
+ "strategy-risk-scale"
63
+ ];
64
+ var sha256 = (contents) => (0, import_node_crypto.createHash)("sha256").update(contents).digest("hex");
65
+ var toProjectPath = (...parts) => import_node_path.default.posix.join(...parts);
66
+ var readDirectory = (directory, projectDirectory, files) => {
67
+ for (const entry of (0, import_node_fs.readdirSync)(directory, { withFileTypes: true }).sort(
68
+ (left, right) => left.name.localeCompare(right.name)
69
+ )) {
70
+ const absolutePath = import_node_path.default.join(directory, entry.name);
71
+ const projectPath = toProjectPath(projectDirectory, entry.name);
72
+ if (entry.isDirectory()) {
73
+ readDirectory(absolutePath, projectPath, files);
74
+ continue;
75
+ }
76
+ if (!entry.isFile()) {
77
+ throw new Error(
78
+ `Skill bundle source must contain regular files: ${absolutePath}`
79
+ );
80
+ }
81
+ files[projectPath] = (0, import_node_fs.readFileSync)(absolutePath, "utf8");
82
+ }
83
+ };
84
+ var calculateBundleSha256 = (fileHashes) => sha256(
85
+ Object.entries(fileHashes).sort(([left], [right]) => left.localeCompare(right)).map(([filePath, fileSha256]) => `${filePath}\0${fileSha256}`).join("\n")
86
+ );
87
+ var createProjectSkillBundle = (canonicalSkillsRoot) => {
88
+ const files = {};
89
+ for (const skillName of PROJECT_SKILL_NAMES) {
90
+ const skillRoot = import_node_path.default.join(canonicalSkillsRoot, skillName);
91
+ if (!(0, import_node_fs.existsSync)(import_node_path.default.join(skillRoot, "SKILL.md"))) {
92
+ throw new Error(`Missing canonical skill: ${skillName}`);
93
+ }
94
+ readDirectory(
95
+ skillRoot,
96
+ toProjectPath(".codex", "skills", skillName),
97
+ files
98
+ );
99
+ }
100
+ const fileHashes = Object.fromEntries(
101
+ Object.entries(files).map(([filePath, contents]) => [
102
+ filePath,
103
+ sha256(contents)
104
+ ])
105
+ );
106
+ const manifest = {
107
+ schema: "tradejs-skill-bundle/v1",
108
+ source: "TradeJS-Dev/TradeJS:.codex/skills",
109
+ bundleSha256: calculateBundleSha256(fileHashes),
110
+ skills: [...PROJECT_SKILL_NAMES],
111
+ files: Object.fromEntries(
112
+ Object.entries(fileHashes).sort(
113
+ ([left], [right]) => left.localeCompare(right)
114
+ )
115
+ )
116
+ };
117
+ return {
118
+ manifest,
119
+ files: {
120
+ ...files,
121
+ [PROJECT_SKILL_BUNDLE_MANIFEST]: `${JSON.stringify(manifest, null, 2)}
122
+ `
123
+ }
124
+ };
125
+ };
126
+ var readPackagedSkillBundle = (bundleRoot) => {
127
+ const files = {};
128
+ readDirectory(bundleRoot, "", files);
129
+ const manifestContents = files[PROJECT_SKILL_BUNDLE_MANIFEST];
130
+ if (!manifestContents) {
131
+ throw new Error(`Missing packaged ${PROJECT_SKILL_BUNDLE_MANIFEST}`);
132
+ }
133
+ const manifest = JSON.parse(manifestContents);
134
+ if (manifest.schema !== "tradejs-skill-bundle/v1" || manifest.source !== "TradeJS-Dev/TradeJS:.codex/skills" || JSON.stringify(manifest.skills) !== JSON.stringify(PROJECT_SKILL_NAMES) || manifest.bundleSha256 !== calculateBundleSha256(manifest.files)) {
135
+ throw new Error("Invalid packaged TradeJS skill bundle manifest");
136
+ }
137
+ const packagedFilePaths = Object.keys(files).filter((filePath) => filePath !== PROJECT_SKILL_BUNDLE_MANIFEST).sort();
138
+ if (JSON.stringify(packagedFilePaths) !== JSON.stringify(Object.keys(manifest.files).sort())) {
139
+ throw new Error("Packaged TradeJS skill bundle contains unbound files");
140
+ }
141
+ for (const [filePath, expectedSha256] of Object.entries(manifest.files)) {
142
+ const contents = files[filePath];
143
+ if (contents === void 0 || sha256(contents) !== expectedSha256) {
144
+ throw new Error(`Packaged TradeJS skill bundle mismatch: ${filePath}`);
145
+ }
146
+ }
147
+ return { files, manifest };
148
+ };
149
+ var writeProjectSkillBundle = (canonicalSkillsRoot, outputRoot) => {
150
+ const { files, manifest } = createProjectSkillBundle(canonicalSkillsRoot);
151
+ (0, import_node_fs.rmSync)(outputRoot, { recursive: true, force: true });
152
+ for (const [relativePath, contents] of Object.entries(files)) {
153
+ const destination = import_node_path.default.join(outputRoot, relativePath);
154
+ (0, import_node_fs.mkdirSync)(import_node_path.default.dirname(destination), { recursive: true });
155
+ (0, import_node_fs.writeFileSync)(destination, contents, "utf8");
156
+ }
157
+ return manifest;
158
+ };
159
+ var isManagedSkillPath = (relativePath) => {
160
+ const normalized = relativePath.replaceAll("\\", "/");
161
+ return normalized === PROJECT_SKILL_BUNDLE_MANIFEST || normalized.startsWith(".codex/skills/") && !normalized.includes("../") && !import_node_path.default.posix.isAbsolute(normalized);
162
+ };
163
+ var readInstalledManifest = (projectRoot) => {
164
+ const manifestPath = import_node_path.default.join(projectRoot, PROJECT_SKILL_BUNDLE_MANIFEST);
165
+ if (!(0, import_node_fs.existsSync)(manifestPath)) return null;
166
+ const manifest = JSON.parse(
167
+ (0, import_node_fs.readFileSync)(manifestPath, "utf8")
168
+ );
169
+ if (manifest.schema !== "tradejs-skill-bundle/v1") {
170
+ throw new Error(`Unsupported installed skill bundle: ${manifestPath}`);
171
+ }
172
+ return manifest;
173
+ };
174
+ var syncProjectSkillBundle = (projectRoot, bundleFiles) => {
175
+ if (!(0, import_node_fs.existsSync)(projectRoot) || !(0, import_node_fs.statSync)(projectRoot).isDirectory()) {
176
+ throw new Error(`Project directory does not exist: ${projectRoot}`);
177
+ }
178
+ const newManifest = JSON.parse(
179
+ bundleFiles[PROJECT_SKILL_BUNDLE_MANIFEST]
180
+ );
181
+ const installedManifest = readInstalledManifest(projectRoot);
182
+ for (const [relativePath, contents] of Object.entries(bundleFiles)) {
183
+ if (!isManagedSkillPath(relativePath)) {
184
+ throw new Error(`Unsafe managed skill path: ${relativePath}`);
185
+ }
186
+ const destination = import_node_path.default.resolve(projectRoot, relativePath);
187
+ if (!destination.startsWith(`${import_node_path.default.resolve(projectRoot)}${import_node_path.default.sep}`)) {
188
+ throw new Error(
189
+ `Managed skill path escapes the project: ${relativePath}`
190
+ );
191
+ }
192
+ if ((0, import_node_fs.existsSync)(destination) && relativePath !== PROJECT_SKILL_BUNDLE_MANIFEST) {
193
+ const currentContents = (0, import_node_fs.readFileSync)(destination, "utf8");
194
+ const installedSha256 = installedManifest?.files[relativePath];
195
+ const isKnownInstalledFile = installedSha256 !== void 0 && sha256(currentContents) === installedSha256;
196
+ if (!isKnownInstalledFile && currentContents !== contents) {
197
+ throw new Error(
198
+ `Refusing to overwrite a modified skill: ${relativePath}`
199
+ );
200
+ }
201
+ }
202
+ }
203
+ for (const [relativePath, installedSha256] of Object.entries(
204
+ installedManifest?.files ?? {}
205
+ )) {
206
+ if (newManifest.files[relativePath] !== void 0) continue;
207
+ if (!isManagedSkillPath(relativePath)) {
208
+ throw new Error(`Unsafe installed skill path: ${relativePath}`);
209
+ }
210
+ const obsoletePath = import_node_path.default.resolve(projectRoot, relativePath);
211
+ if (!(0, import_node_fs.existsSync)(obsoletePath)) continue;
212
+ const contents = (0, import_node_fs.readFileSync)(obsoletePath);
213
+ if (sha256(contents) !== installedSha256) {
214
+ throw new Error(
215
+ `Refusing to remove a modified obsolete skill: ${relativePath}`
216
+ );
217
+ }
218
+ (0, import_node_fs.rmSync)(obsoletePath);
219
+ }
220
+ for (const [relativePath, contents] of Object.entries(bundleFiles)) {
221
+ const destination = import_node_path.default.join(projectRoot, relativePath);
222
+ (0, import_node_fs.mkdirSync)(import_node_path.default.dirname(destination), { recursive: true });
223
+ (0, import_node_fs.writeFileSync)(destination, contents, "utf8");
224
+ }
225
+ return newManifest;
226
+ };
227
+
228
+ // src/index.ts
46
229
  var DEFAULT_PROJECT_NAME = "tradejs-project";
47
230
  var DEFAULT_PORT = 3e3;
231
+ var PACKAGED_SKILL_BUNDLE_ROOT = import_node_path2.default.resolve(__dirname, "skill-bundle");
232
+ var CANONICAL_SKILLS_ROOT = import_node_path2.default.resolve(
233
+ __dirname,
234
+ "..",
235
+ "..",
236
+ "..",
237
+ ".codex",
238
+ "skills"
239
+ );
48
240
  var DEFAULT_INFRASTRUCTURE_PORTS = {
49
241
  postgres: 5432,
50
242
  redis: 6379,
@@ -62,6 +254,7 @@ Options:
62
254
  --no-infra Skip Docker infrastructure and onboarding seed
63
255
  --no-start Do not start the Web UI
64
256
  --no-open Do not open a browser
257
+ --update-skills Update only the managed TradeJS skill bundle in an existing project
65
258
  -h, --help Show this help`);
66
259
  };
67
260
  var readOptionValue = (argv, index) => {
@@ -78,6 +271,7 @@ var parseArgs = (argv) => {
78
271
  let start = true;
79
272
  let open = true;
80
273
  let port = DEFAULT_PORT;
274
+ let updateSkills = false;
81
275
  for (let index = 0; index < argv.length; index += 1) {
82
276
  const arg = argv[index];
83
277
  if (arg === "-h" || arg === "--help") {
@@ -101,6 +295,10 @@ var parseArgs = (argv) => {
101
295
  open = false;
102
296
  continue;
103
297
  }
298
+ if (arg === "--update-skills") {
299
+ updateSkills = true;
300
+ continue;
301
+ }
104
302
  if (arg === "--port") {
105
303
  port = Number(readOptionValue(argv, index));
106
304
  index += 1;
@@ -124,20 +322,35 @@ var parseArgs = (argv) => {
124
322
  if (!install && (infra || start)) {
125
323
  throw new Error("--no-install cannot start infrastructure or the Web UI");
126
324
  }
325
+ if (updateSkills) {
326
+ install = false;
327
+ infra = false;
328
+ start = false;
329
+ open = false;
330
+ }
127
331
  return {
128
- targetDir: targetDir || DEFAULT_PROJECT_NAME,
332
+ targetDir: targetDir || (updateSkills ? "." : DEFAULT_PROJECT_NAME),
129
333
  install,
130
334
  infra,
131
335
  start,
132
336
  open,
133
- port
337
+ port,
338
+ updateSkills
134
339
  };
135
340
  };
136
341
  var packageNameFromDir = (targetDir) => {
137
- const normalized = import_node_path.default.basename(targetDir).toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
342
+ const normalized = import_node_path2.default.basename(targetDir).toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
138
343
  return normalized || DEFAULT_PROJECT_NAME;
139
344
  };
140
- var createAuthSecret = () => (0, import_node_crypto.randomBytes)(32).toString("hex");
345
+ var createAuthSecret = () => (0, import_node_crypto2.randomBytes)(32).toString("hex");
346
+ var readProjectSkillBundle = () => (0, import_node_fs2.existsSync)(
347
+ import_node_path2.default.join(
348
+ PACKAGED_SKILL_BUNDLE_ROOT,
349
+ ".codex",
350
+ "tradejs-skill-bundle.json"
351
+ )
352
+ ) ? readPackagedSkillBundle(PACKAGED_SKILL_BUNDLE_ROOT) : createProjectSkillBundle(CANONICAL_SKILLS_ROOT);
353
+ var stageCanonicalSkillBundle = () => writeProjectSkillBundle(CANONICAL_SKILLS_ROOT, PACKAGED_SKILL_BUNDLE_ROOT);
141
354
  var buildProjectFiles = (targetDir, port, infrastructurePorts = DEFAULT_INFRASTRUCTURE_PORTS) => {
142
355
  const packageName = packageNameFromDir(targetDir);
143
356
  const authSecret = createAuthSecret();
@@ -207,21 +420,40 @@ npm run dev
207
420
 
208
421
  Open [http://localhost:${port}/routes/dashboard](http://localhost:${port}/routes/dashboard).
209
422
  On the first launch, TradeJS asks you to create the local root password.
210
- `
423
+
424
+ ## Codex strategy workflow
425
+
426
+ The project includes focused TradeJS skills under \`.codex/skills\`. Invoke a
427
+ skill with a strategy name, for example:
428
+
429
+ \`$strategy-candidate-report MarketFlushReversal\`
430
+
431
+ Use \`$strategy-forward-start <Strategy>\` only when you want Codex to publish
432
+ and launch the selected candidate as a bounded forward test. It installs the
433
+ exact candidate configuration with \`MAX_LOSS_VALUE=1\` and requires an exact
434
+ deployment/account binding.
435
+ `,
436
+ ...readProjectSkillBundle().files
211
437
  };
212
438
  };
213
439
  var scaffoldProject = (targetDir, port, infrastructurePorts = DEFAULT_INFRASTRUCTURE_PORTS) => {
214
- const absoluteTarget = import_node_path.default.resolve(targetDir);
215
- if ((0, import_node_fs.existsSync)(absoluteTarget) && (0, import_node_fs.readdirSync)(absoluteTarget).length > 0) {
440
+ const absoluteTarget = import_node_path2.default.resolve(targetDir);
441
+ if ((0, import_node_fs2.existsSync)(absoluteTarget) && (0, import_node_fs2.readdirSync)(absoluteTarget).length > 0) {
216
442
  throw new Error(`Target directory is not empty: ${absoluteTarget}`);
217
443
  }
218
- (0, import_node_fs.mkdirSync)(absoluteTarget, { recursive: true });
444
+ (0, import_node_fs2.mkdirSync)(absoluteTarget, { recursive: true });
219
445
  const files = buildProjectFiles(absoluteTarget, port, infrastructurePorts);
220
446
  for (const [relativePath, contents] of Object.entries(files)) {
221
- (0, import_node_fs.writeFileSync)(import_node_path.default.join(absoluteTarget, relativePath), contents, "utf8");
447
+ const destination = import_node_path2.default.join(absoluteTarget, relativePath);
448
+ (0, import_node_fs2.mkdirSync)(import_node_path2.default.dirname(destination), { recursive: true });
449
+ (0, import_node_fs2.writeFileSync)(destination, contents, "utf8");
222
450
  }
223
451
  return absoluteTarget;
224
452
  };
453
+ var updateProjectSkills = (targetDir) => {
454
+ const absoluteTarget = import_node_path2.default.resolve(targetDir);
455
+ return syncProjectSkillBundle(absoluteTarget, readProjectSkillBundle().files);
456
+ };
225
457
  var run = (command, args, cwd) => {
226
458
  const result = (0, import_node_child_process.spawnSync)(command, args, {
227
459
  cwd,
@@ -237,7 +469,7 @@ var run = (command, args, cwd) => {
237
469
  );
238
470
  }
239
471
  };
240
- var localBin = (projectDir, name) => import_node_path.default.join(
472
+ var localBin = (projectDir, name) => import_node_path2.default.join(
241
473
  projectDir,
242
474
  "node_modules",
243
475
  ".bin",
@@ -345,6 +577,13 @@ var main = async () => {
345
577
  printUsage();
346
578
  return;
347
579
  }
580
+ if (options.updateSkills) {
581
+ const manifest = updateProjectSkills(options.targetDir);
582
+ console.log(
583
+ `Updated TradeJS skill bundle ${manifest.bundleSha256} in ${import_node_path2.default.resolve(options.targetDir)}`
584
+ );
585
+ return;
586
+ }
348
587
  const infrastructurePorts = options.infra ? {
349
588
  postgres: await findAvailablePort(5432),
350
589
  redis: await findAvailablePort(6379),
@@ -396,5 +635,7 @@ create-tradejs failed: ${error.message}`);
396
635
  findAvailablePort,
397
636
  main,
398
637
  parseArgs,
399
- scaffoldProject
638
+ scaffoldProject,
639
+ stageCanonicalSkillBundle,
640
+ updateProjectSkills
400
641
  });
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: strategy-candidate-compare
3
+ description: Compare one TradeJS strategy’s latest selected best candidate with the exact composition currently deployed or configured for production on a common evidence scope. Use for candidate-vs-production questions; do not tune, publish, deploy, or change risk.
4
+ ---
5
+
6
+ # Strategy Candidate Compare
7
+
8
+ Require one exact strategy name.
9
+
10
+ ## Boundary
11
+
12
+ This is a read-only comparison. Do not edit source/config, select new
13
+ parameters, publish, deploy, or alter orders. A single cache-only bridge run is
14
+ allowed only when the two frozen compositions lack a valid common-scope result;
15
+ it must not change either composition.
16
+
17
+ ## Resolve both identities
18
+
19
+ 1. Resolve the latest explicitly selected, reproducible candidate using the
20
+ same rules as `$strategy-candidate-report`.
21
+ 2. Resolve production from the deployed package manifest and Git-owned
22
+ `tradejs.config.ts`, including effective defaults, package lock, deterministic
23
+ gate, runtime context, `strategyRevision`, and `deploymentCompositionId`.
24
+ Redis backtest configs and legacy strategy keys are not production truth.
25
+ 3. If live evidence is unavailable, use the newest immutable deployment
26
+ manifest and label production identity as unconfirmed rather than guessing.
27
+
28
+ ## Make the comparison fair
29
+
30
+ Use the maximum common timestamp range, point-in-time universe, symbols,
31
+ interval, fees, slippage, entry delay, risk unit, and execution assumptions.
32
+ Normalize PnL and drawdown per unit of `MAX_LOSS_VALUE` when production and the
33
+ candidate use different risk. Never compare raw money at different sizing as
34
+ strategy quality.
35
+
36
+ If a bridge is necessary, freeze the comparison before running it, use cached
37
+ history, run both exact compositions, and record the new run as evaluation—not
38
+ optimization. Do not inspect one result and alter the other.
39
+
40
+ ## Output
41
+
42
+ Show side-by-side absolute values and candidate-minus-production deltas for
43
+ ALL/LONG/SHORT across full/max coverage and continuous 365d/180d/90d/30d/7d
44
+ windows, plus 3y/4y/5y-or-max when covered. Include `N`, net PnL, expectancy,
45
+ PF, win rate, Sharpe/PSR/DSR, MaxDD, worst trade, loss streak, losing-month
46
+ streak, recovery, cadence, stability, concentration, and cost stress.
47
+
48
+ Conclude with:
49
+
50
+ - identity/parity confidence;
51
+ - what improved, regressed, or remains underpowered;
52
+ - whether the candidate remains the selected best candidate under the frozen
53
+ objective;
54
+ - one exact next action. Do not launch it from this skill.
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: strategy-candidate-report
3
+ description: Show the latest selected best candidate for one TradeJS strategy, including exact lineage, configuration, gate, freshness, chart, and professional risk-adjusted metrics. Use for “show the best candidate” or “latest candidate metrics”; do not run new research or change runtime state.
4
+ ---
5
+
6
+ # Strategy Candidate Report
7
+
8
+ Require one exact strategy name. Work from the TradeJS project that owns
9
+ `tradejs.config.ts`, `data/`, and research evidence.
10
+
11
+ ## Boundary
12
+
13
+ This is a reporting skill. Do not edit strategy source or configuration, start
14
+ backtests, publish packages, change `tradejs.config.ts`, or mutate a runtime.
15
+ Creating a report or chart under `output/` is allowed.
16
+
17
+ ## Select the candidate
18
+
19
+ 1. Find the newest completed research lineage that explicitly selected a best
20
+ candidate and has checksum-verifiable evidence. Do not equate newest file,
21
+ largest PnL, an incomplete run, or an old production config with “best.”
22
+ 2. Prefer a verified strategy-release/candidate manifest. If evidence exists
23
+ only in notes, require the exact source SHA, resolved config, gate identity,
24
+ data bounds, costs, and artifact hashes before calling it reproducible.
25
+ 3. If there is no selected reproducible candidate, say so. Show the strongest
26
+ known evidence separately, but do not silently promote it.
27
+
28
+ ## Report
29
+
30
+ Show:
31
+
32
+ - candidate ID, selection time, research ID, source/package revision, dirty
33
+ state, core config, deterministic gate and direction policy;
34
+ - data start/end, universe provenance, fees/slippage, train/discovery/test
35
+ exposure, and the newest evaluated candle;
36
+ - ALL, LONG, and SHORT rows for full/max coverage plus available continuous
37
+ 3y, 4y, 5y-or-max, 365d, 180d, 90d, 30d, and 7d windows;
38
+ - `N`, net PnL, PnL/trade, PF, win rate, Sharpe, probabilistic/deflated Sharpe
39
+ when available, realized MaxDD, worst trade, maximum loss streak, maximum
40
+ losing-month streak, recovery duration, and cadence;
41
+ - walk-forward/fold and regime stability, concentration, cost stress, and all
42
+ recorded limitations or failed checks;
43
+ - a stored equity/drawdown chart, or rebuild the chart only from the frozen
44
+ candidate trades and label it as report rendering rather than new evidence.
45
+
46
+ Classify every window by independent support: fewer than 20 events is
47
+ underpowered, 20–49 is diagnostic, and 50+ is selection-grade. A zero-trade or
48
+ sparse 7d/30d row must remain visible, but it is not a standalone veto and does
49
+ not imply that anyone must wait for a calendar deadline.
50
+
51
+ Finish with one exact next skill: compare, plan, revalidate, or forward-start.
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: strategy-forward-start
3
+ description: Publish and start one exact TradeJS strategy candidate as a bounded production forward test with MAX_LOSS_VALUE=1. Supports either the latest eligible best candidate or a checksum-reproducible historically promising candidate that the user explicitly names for prospective-only learning. Use only when the user explicitly asks to launch the forward test.
4
+ ---
5
+
6
+ # Strategy Forward Start
7
+
8
+ Require one exact strategy name. Invocation of this skill is authorization to
9
+ roll out only that strategy at `MAX_LOSS_VALUE=1`. By default, use its latest
10
+ checksum-verified, forward-eligible best candidate. If the user explicitly
11
+ names a different historically promising candidate and requests a production
12
+ forward test, use the operator-directed prospective mode below. Neither mode is
13
+ authorization to retune the candidate, increase risk, or touch unrelated
14
+ strategies.
15
+
16
+ ## Operator-directed prospective mode
17
+
18
+ An explicitly named candidate may proceed even when an immutable research
19
+ artifact selected another candidate, marked runtime mutation as disallowed, or
20
+ reported a sparse, flat, or negative recent diagnostic cohort. These facts
21
+ remain visible diagnostics; they are not by themselves blockers for collecting
22
+ new prospective evidence at risk 1.
23
+
24
+ Use this mode only when all of the following are true:
25
+
26
+ - the user names the exact strategy and candidate and explicitly authorizes its
27
+ production forward test with `MAX_LOSS_VALUE=1`;
28
+ - the exact expression, direction policy, effective core configuration, source
29
+ and data lineage, and evidence hashes are reproducible without new tuning;
30
+ - the maximum-covered historical window has positive net PnL and profit factor
31
+ above 1, and its full-period metrics and chart remain available;
32
+ - a new immutable operator-authorization artifact references the original
33
+ selection/freeze and the contrary or underpowered evidence; and
34
+ - the artifact states that the rollout is prospective-only and does not rewrite
35
+ the old verdict or upgrade the candidate to historically validated.
36
+
37
+ Do not edit an old freeze, selection, progress, decision, or research verdict
38
+ to manufacture eligibility. Implement a research-only expression in the owned
39
+ strategy package before release, with focused tests that lock the exact
40
+ behavior.
41
+
42
+ ## Preconditions
43
+
44
+ Resolve the exact runtime user, deployment, account, connector, symbols, and
45
+ release mechanism from Git-owned project/deployment configuration. Resolve the
46
+ candidate’s source SHA, package version, lockfile boundary, full effective core
47
+ config, deterministic gate/context, direction policy, evidence hashes, and
48
+ either standard forward eligibility or the immutable operator authorization.
49
+ Do not infer production from Redis.
50
+
51
+ Stop before mutation if the target binding is ambiguous, credentials/registry
52
+ authorization is missing, the candidate is not reproducible or implementable,
53
+ the maximum-covered historical edge is non-positive, required evidence/chart
54
+ hashes are missing, required checks fail, another rollout is active, or safe
55
+ atomic deployment is unavailable. These are operational or falsifiability
56
+ boundaries and operator-directed mode does not waive them. Give the exact
57
+ command or UI boundary the user must complete; never start an interactive
58
+ authentication flow.
59
+
60
+ ## Release and configure
61
+
62
+ 1. Re-run source package checks at the selected commit. If the candidate uses
63
+ unpublished source, commit and push the complete accumulated release range,
64
+ publish one immutable stable package through the repository’s existing
65
+ release workflow, and verify the registry artifact. Do not cherry-pick only
66
+ one fix out of an accumulated unshipped range.
67
+ 2. Install the exact package version in the Project and commit the lockfile.
68
+ 3. Write the candidate’s complete reviewed configuration to the selected
69
+ deployment in the Git-owned Project runtime configuration and force
70
+ `MAX_LOSS_VALUE=1`:
71
+ - if the strategy is absent, add and enable it;
72
+ - if it runs a different composition, replace that strategy declaration in
73
+ one guarded cutover while preserving unrelated strategies;
74
+ - if the exact composition already runs at risk 1, make no config change and
75
+ continue with idempotent verification.
76
+ 4. Run strict Project checks and runtime-control verification. Commit and push
77
+ the complete Project release range, publish/deploy its exact immutable tip
78
+ through the configured production workflow, and wait for the deployment
79
+ handoff to finish.
80
+
81
+ ## Verify the forward test
82
+
83
+ Confirm the deployed package/config manifest, `strategyRevision`,
84
+ `deploymentCompositionId`, account binding, enabled strategy, risk value,
85
+ heartbeat, and that exactly one managed runtime process owns the deployment.
86
+ Verify that the configured runtime actually permits bounded order placement;
87
+ signal-only evaluation is not a started forward test.
88
+
89
+ Never place, cancel, or close an order manually and never launch an unmanaged
90
+ background daemon. Do not wait for profitable 7d/30d/180d tails: forward
91
+ learning starts immediately at risk 1. Return the authorization mode and
92
+ artifact, preserved contrary evidence, commits, package version, deployment
93
+ identity, exact config diff, verification evidence, monitoring command, and
94
+ rollback/stop procedure.
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: strategy-forward-status
3
+ description: Inspect the live status and evidence of one TradeJS strategy’s forward test, including deployed identity, parity, orders, normalized performance, drawdown, execution quality, and whether the test is still informative. Read-only; does not scale, stop, or deploy.
4
+ ---
5
+
6
+ # Strategy Forward Status
7
+
8
+ Require one exact strategy name and resolve the exact runtime user/deployment.
9
+
10
+ ## Boundary
11
+
12
+ This skill is read-only. Do not edit source/config, pause/resume, place/cancel
13
+ orders, scale risk, publish, or deploy. Missing local Redis keys are not proof
14
+ that production did not run; prefer immutable runtime evidence from the target
15
+ deployment.
16
+
17
+ ## Inspect
18
+
19
+ Verify the deployed manifest, package version, full effective config,
20
+ `strategyRevision`, `deploymentCompositionId`, account/connector/symbol binding,
21
+ `MAX_LOSS_VALUE`, heartbeat, and single-process ownership. Compare all of them
22
+ with the selected candidate manifest and classify exact match, explainable
23
+ drift, or invalid forward evidence.
24
+
25
+ Collect runtime evidence and reconcile signal → gate decision → order → fill →
26
+ exit. Report:
27
+
28
+ - independent closed positions, open exposure, cadence, and elapsed market
29
+ coverage;
30
+ - PnL and drawdown normalized by the candidate risk unit;
31
+ - expectancy, PF, win rate, Sharpe when meaningful, worst loss, current and
32
+ maximum loss streak, losing-month streak, and recovery;
33
+ - fees, slippage, rejects, latency, partial fills, missed/duplicate decisions,
34
+ parity mismatches, symbol/regime concentration, and historical-envelope
35
+ utilization;
36
+ - prospective evidence only—never merge live observations back into the
37
+ historical selection sample.
38
+
39
+ Classify the forward test as `RUNNING_INFORMATIVE`, `RUNNING_UNDERPOWERED`,
40
+ `PAUSED_OR_STOPPED`, `COMPOSITION_DRIFT`, or `EXECUTION_INVALID`. Calendar age
41
+ alone is not success or failure; weight the number and diversity of independent
42
+ events. Finish with one exact recommendation: keep collecting, diagnose via a
43
+ new research task, stop through the deployment runbook, or invoke
44
+ `$strategy-risk-scale`.
@@ -0,0 +1,51 @@
1
+ ---
2
+ name: strategy-improvement-plan
3
+ description: Analyze how one TradeJS strategy could be improved from its source, latest candidate, production comparison, traces, and rejected hypotheses. Use for an opportunity map or research plan; do not run experiments, edit code, or change production.
4
+ ---
5
+
6
+ # Strategy Improvement Plan
7
+
8
+ Require one exact strategy name. Read the strategy repository rules, source,
9
+ tests, latest selected candidate, production composition, prior candidate
10
+ ledger, rejection reasons, and available signal-to-exit traces.
11
+
12
+ ## Boundary
13
+
14
+ This skill produces a causal research plan only. Do not run backtests or gate
15
+ searches, edit source, create a new candidate, publish, deploy, or change risk.
16
+
17
+ ## Analysis
18
+
19
+ Reconstruct the market thesis and map evidence across:
20
+
21
+ - setup formation and point-in-time data quality;
22
+ - entry timing, direction policy, and regime dependence;
23
+ - stop/target geometry, payoff asymmetry, and worst-loss mechanics;
24
+ - position lifecycle, shared occupancy, cooldown, and exits;
25
+ - deterministic gate precision, rejection coverage, and missing context;
26
+ - symbol/time concentration, capacity, fees, slippage, and execution parity.
27
+
28
+ Do not recommend generic threshold grids. For every proposed change state the
29
+ mechanism, exact source/config seam, predicted trade-identity and metric effect,
30
+ minimum falsifying observation, affected side/regime, and overfit risk.
31
+
32
+ ## Professional objective
33
+
34
+ Rank hypotheses hierarchically:
35
+
36
+ 1. causal validity, trace reconciliation, and absence of leakage;
37
+ 2. positive out-of-sample expectancy per risk after costs with enough
38
+ independent support;
39
+ 3. Sharpe/PSR/DSR, drawdown/tail loss, recovery, loss streaks, and losing-month
40
+ streaks;
41
+ 4. walk-forward/regime stability, concentration, cost robustness, and
42
+ executable cadence;
43
+ 5. full-period PnL and win rate as economic diagnostics, never sole targets.
44
+
45
+ Recent 7d/30d/180d rows describe the current regime with support-aware weight;
46
+ they are not mandatory profit gates when sparse. Avoid objectives that improve
47
+ Sharpe or win rate by suppressing almost all trades.
48
+
49
+ Return an ordered plan with one exploit hypothesis, one repair hypothesis, one
50
+ explore/falsify hypothesis, frozen evaluation criteria, expected cost, and the
51
+ exact invocation of `$strategy-improvement-research`.
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: strategy-improvement-research
3
+ description: Conduct a new bounded professional research lineage to improve one TradeJS strategy’s core and deterministic gate, revalidating prior candidates first and continuing beyond audits or failed first rounds until a reproducible best candidate is frozen. Does not publish or change production.
4
+ ---
5
+
6
+ # Strategy Improvement Research
7
+
8
+ Require one exact strategy name. Run operational commands from the TradeJS
9
+ project. Before applying candidate source edits, create one dedicated strategy
10
+ worktree per immutable research lineage from the exact frozen production or
11
+ control SHA. Keep the canonical strategy checkout clean, run source edits and
12
+ checks in the worktree, and set `PROJECT_CWD` to the canonical Project and
13
+ `TRADEJS_SOURCE_REPOSITORY_ROOT` to the exact worktree. If the task is already
14
+ scoped to a dedicated worktree, validate and reuse it instead of nesting
15
+ another one. A lineage that only re-scores existing artifacts and makes no
16
+ source edits does not need a worktree.
17
+
18
+ ## Source isolation
19
+
20
+ - Inspect the owning repository's worktree list and verify the frozen baseline
21
+ SHA before creating or reusing the lineage worktree. Do not use an unrelated
22
+ old worktree, scratch directory, generated artifact, or clone as the source
23
+ root.
24
+ - Evaluate candidates sequentially in the same lineage worktree. Before
25
+ replacing a rejected candidate, freeze its exact source diff, build hash,
26
+ resolved config, run lineage, and outcome in Project-owned immutable
27
+ evidence, then restore only that disposable worktree to the frozen baseline.
28
+ - Keep any temporary Project package overlay explicit and restore it to the
29
+ verified stable package after each candidate or before handoff. A source
30
+ worktree does not isolate `TradeJS-Project/node_modules`.
31
+ - If no new candidate is selected, verify the canonical checkout was never
32
+ changed and remove the disposable worktree only after all evidence is
33
+ frozen. If a candidate is selected, commit only that candidate and its tests
34
+ on the worktree branch and hand off the exact commit SHA; do not retain
35
+ rejected behavior as source commits.
36
+
37
+ ## Authority boundary
38
+
39
+ You may refresh research artifacts, run cache-backed research, edit strategy
40
+ core/gate/tests, and commit the selected source candidate locally. Do not push,
41
+ publish packages, edit the Project’s production composition, deploy, start a
42
+ forward test, or change live risk. Those belong to `$strategy-forward-start`.
43
+
44
+ ## Required contour
45
+
46
+ 1. Start a new immutable research lineage. Freeze data bounds, point-in-time
47
+ universe, symbols, interval, fees/slippage, execution assumptions, risk
48
+ normalization, objective, holdout exposure, and trial ledger.
49
+ 2. Inventory and deduplicate prior production and research candidates. Re-score
50
+ compatible candidates and exact-bridge any plausibly competitive
51
+ incompatible candidate on the new common period before inventing changes.
52
+ Old winners are competitors, not automatic controls and not erased.
53
+ 3. Reconstruct the market thesis and opportunity map. Select at least three
54
+ distinct causal families: exploit, repair, and explore/falsify.
55
+ 4. Evaluate one preregistered candidate per family. Continue viable families
56
+ with evidence-driven children and use remaining slots for direction-policy
57
+ or Pareto rescue. The default cap is 12 genuinely new behaviors. An audit,
58
+ parser fix, no-op, or rescoring of an old behavior does not consume a slot.
59
+ 5. Do not stop at the audit, baseline, first failed round, or a sparse recent
60
+ tail. Stop only when a reproducible best candidate is frozen, the fresh
61
+ budget is exhausted, or every remaining family has a recorded hard causal
62
+ blocker.
63
+ 6. Keep one chronological tail sealed during discovery when coverage permits.
64
+ Open it once for the final selected behavior. Track all exposed tests for
65
+ multiple-testing/deflated-Sharpe interpretation.
66
+ 7. Run package formatting, typecheck, tests, and build in the lineage worktree.
67
+ Commit only the selected candidate and its tests on that worktree branch;
68
+ preserve rejected experiments as immutable evidence, not source clutter.
69
+
70
+ ## Selection objective
71
+
72
+ First require causal/reconciliation validity and positive aggregate
73
+ out-of-sample expectancy per risk after costs. Then rank by probabilistic or
74
+ deflated Sharpe, realized MaxDD/tail/recovery, worst loss and loss streaks,
75
+ losing-month streak, fold/regime stability, concentration, cost robustness,
76
+ and cadence. Full-period PnL, win rate, and 7d/30d/180d profitability are
77
+ diagnostics, not standalone optimization targets. Classify window support as
78
+ underpowered below 20 events, diagnostic at 20–49, and selection-grade at 50+.
79
+
80
+ ## Handoff
81
+
82
+ Create or update the existing checksum-verified strategy-release/candidate
83
+ manifest rather than inventing a second pointer format. Freeze candidate ID,
84
+ source/package SHA, full resolved core config, deterministic gate/context,
85
+ direction policy, evidence hashes, trial count, metric matrix, chart, freshness,
86
+ limitations, and forward-test eligibility. End with the selected candidate,
87
+ why it beat production and prior candidates, and exactly one next skill.
@@ -0,0 +1,47 @@
1
+ ---
2
+ name: strategy-period-revalidate
3
+ description: Re-evaluate one TradeJS strategy’s production composition and strongest prior candidates on a newly extended common period without retuning them. Use when new market data is available or old candidates must be revalidated under the current metric objective.
4
+ ---
5
+
6
+ # Strategy Period Revalidate
7
+
8
+ Require one exact strategy name and use the TradeJS project as the evidence
9
+ root.
10
+
11
+ ## Boundary
12
+
13
+ This is frozen-behavior evaluation. Do not alter strategy logic, gate rules,
14
+ parameters, direction policy, or runtime state after seeing the new period. Do
15
+ not publish or deploy. A configuration change belongs to a new
16
+ `$strategy-improvement-research` lineage.
17
+
18
+ ## Cohort
19
+
20
+ Include the exact current production composition, latest selected best
21
+ candidate, strongest prior aggregate candidate, strongest side-specific
22
+ candidate when distinct, and any currently running forward candidate. Deduplicate
23
+ identical core/gate/context behavior. Record why any plausible prior candidate
24
+ cannot be reproduced.
25
+
26
+ ## Run
27
+
28
+ 1. Freeze the new common end time, maximum common start, point-in-time universe,
29
+ costs, execution assumptions, and candidate identities before evaluation.
30
+ 2. Use existing cached history first. If the requested new tail is absent,
31
+ fetch only that missing tail through the supported TradeJS data path, then
32
+ fingerprint the resulting coverage; never silently rewrite old history.
33
+ 3. Evaluate all frozen candidates on identical scopes. Do not eliminate a
34
+ candidate after one window and do not tune against the new observations.
35
+ 4. Recompute ALL/LONG/SHORT full/max, 3y/4y/5y-or-max, 365d, 180d, 90d, 30d,
36
+ and 7d rows where covered, including zero-activity rows. Report PnL/risk,
37
+ PF, expectancy, win rate, Sharpe/PSR/DSR, MaxDD, worst loss, loss streak,
38
+ losing-month streak, recovery, cadence, stability, concentration, and cost
39
+ stress.
40
+ 5. Weight recent windows by independent support: below 20 underpowered, 20–49
41
+ diagnostic, 50+ selection-grade. Never require waiting 7, 30, or 180
42
+ calendar days merely to obtain a verdict.
43
+
44
+ Update the immutable comparison evidence and candidate freshness without
45
+ rewriting the original selection record. State whether the incumbent remains
46
+ best under the frozen objective and choose exactly one next skill: report,
47
+ research, forward-start, forward-status, or risk-scale.
@@ -0,0 +1,44 @@
1
+ ---
2
+ name: strategy-risk-scale
3
+ description: Increase MAX_LOSS_VALUE for a currently running TradeJS forward strategy while preserving the exact core, gate, context, direction policy, package, and deployment composition. Use only after explicit user instruction to increase risk; never switch candidates or wait for fixed calendar tails.
4
+ ---
5
+
6
+ # Strategy Risk Scale
7
+
8
+ Require one exact strategy name. Invocation authorizes one bounded risk step
9
+ for the currently deployed composition only.
10
+
11
+ ## Invariants
12
+
13
+ Freeze and verify source/package revision, full config, deterministic gate and
14
+ context, direction policy, universe, connector/account, deployment, and current
15
+ `strategyRevision`/`deploymentCompositionId`. Apart from `MAX_LOSS_VALUE`, all
16
+ strategy behavior must remain identical. If anything else differs, stop and
17
+ route to `$strategy-forward-start` or `$strategy-improvement-research`.
18
+
19
+ Do not use “7 profitable days” or “wait 30 days” as a generic gate. Use the
20
+ candidate’s preregistered event-driven scaling policy. If none exists, require
21
+ enough independent closed positions to estimate expectancy and drawdown,
22
+ positive after-cost normalized expectancy, execution/parity integrity,
23
+ acceptable slippage and concentration, and normalized drawdown/tail losses
24
+ inside the frozen historical stress envelope. Treat fewer than 20 independent
25
+ events as underpowered and 20–49 as diagnostic unless unusually strong
26
+ strategy-specific evidence justifies the recorded exception.
27
+
28
+ ## Scale
29
+
30
+ 1. Produce a read-only forward status and scaling decision first. Refuse the
31
+ step on composition drift, execution-invalid evidence, unresolved critical
32
+ parity errors, breached loss envelope, or missing deployment binding.
33
+ 2. Increase risk by only one preregistered step, never more than 2× the current
34
+ value and never above the candidate’s approved cap.
35
+ 3. Change only `MAX_LOSS_VALUE` in Git-owned `tradejs.config.ts`. Run strict
36
+ checks, commit and push the complete Project release range, publish/deploy
37
+ the exact immutable tip through the existing workflow, and verify the new
38
+ deployment atomically.
39
+ 4. Record a risk-scale marker linking old/new values and deployment identities;
40
+ keep historical and live performance normalized to a common risk unit.
41
+
42
+ Never place, cancel, or close orders manually and never start an unmanaged
43
+ daemon. Return the evidence decision, old/new risk, Project commit, deployment
44
+ identity, verification, monitoring threshold, and rollback condition.
@@ -0,0 +1,25 @@
1
+ {
2
+ "schema": "tradejs-skill-bundle/v1",
3
+ "source": "TradeJS-Dev/TradeJS:.codex/skills",
4
+ "bundleSha256": "61f0c85bbb29614ba43d447e808c9321fac85aad391f707ff18f0d51fcaace65",
5
+ "skills": [
6
+ "strategy-candidate-report",
7
+ "strategy-candidate-compare",
8
+ "strategy-improvement-plan",
9
+ "strategy-improvement-research",
10
+ "strategy-period-revalidate",
11
+ "strategy-forward-start",
12
+ "strategy-forward-status",
13
+ "strategy-risk-scale"
14
+ ],
15
+ "files": {
16
+ ".codex/skills/strategy-candidate-compare/SKILL.md": "34dbca2c77ce74836f5c264131cefb751313147128ab1c3f947002f975be051c",
17
+ ".codex/skills/strategy-candidate-report/SKILL.md": "3cad1241ce2107d7e30a5d78eafd6429514a10d1a8e9cf3d0e97ffef9d691ab6",
18
+ ".codex/skills/strategy-forward-start/SKILL.md": "1591bd1c64864283320793b3c0bb4e1677aab960951ef8b487a1101ca7b6f82c",
19
+ ".codex/skills/strategy-forward-status/SKILL.md": "b41f117680259fd7b4d5cbe3c0a1be75a42f08c8cf78f9ad7ccb0d90bfc66269",
20
+ ".codex/skills/strategy-improvement-plan/SKILL.md": "f5f0f390941dd3332890a2f0ffae1248abde4925db2cf49a41c0c0c1b47e7864",
21
+ ".codex/skills/strategy-improvement-research/SKILL.md": "38fe575954db303dc28763432b2bbc7bc07054adb56196810f15490755a75f76",
22
+ ".codex/skills/strategy-period-revalidate/SKILL.md": "f367ba1c632506a7d9bf92662a40b61df55f7a56ad04f3600a475b3c365bbbcb",
23
+ ".codex/skills/strategy-risk-scale/SKILL.md": "2c07846c9da2fd622ea6f5586c42863fc27b35a7d1d00614d5bbe0719da4d39f"
24
+ }
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-tradejs",
3
- "version": "3.1.21",
3
+ "version": "3.1.22-beta.238",
4
4
  "description": "Create a ready-to-run TradeJS project with local infrastructure and the Web UI.",
5
5
  "keywords": [
6
6
  "tradejs",
@@ -33,7 +33,8 @@
33
33
  "access": "public"
34
34
  },
35
35
  "scripts": {
36
- "build": "tsup",
36
+ "build": "tsup && node ./scripts/stage-skill-bundle.mjs",
37
+ "prepack": "yarn build",
37
38
  "typecheck": "tsc -p ./tsconfig.json --noEmit"
38
39
  },
39
40
  "devDependencies": {