@reefclaw/openclaw-plugin 0.1.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.
Files changed (371) hide show
  1. package/.gitignore +8 -0
  2. package/audit/mode-transition-audit.d.ts +11 -0
  3. package/audit/mode-transition-audit.js +29 -0
  4. package/balance-utils.d.ts +36 -0
  5. package/balance-utils.js +98 -0
  6. package/bridge/bridge.d.ts +109 -0
  7. package/bridge/bridge.js +1036 -0
  8. package/bridge/config.d.ts +43 -0
  9. package/bridge/config.js +176 -0
  10. package/bridge/connector.d.ts +52 -0
  11. package/bridge/connector.js +293 -0
  12. package/bridge/event-replay-buffer.d.ts +43 -0
  13. package/bridge/event-replay-buffer.js +109 -0
  14. package/bridge/gateway/event-parser.d.ts +209 -0
  15. package/bridge/gateway/event-parser.js +793 -0
  16. package/bridge/gateway/gateway-config.d.ts +39 -0
  17. package/bridge/gateway/gateway-config.js +86 -0
  18. package/bridge/gateway/gateway-http-client.d.ts +50 -0
  19. package/bridge/gateway/gateway-http-client.js +165 -0
  20. package/bridge/gateway/gateway-ws-client.d.ts +116 -0
  21. package/bridge/gateway/gateway-ws-client.js +417 -0
  22. package/bridge/gateway/poller.d.ts +146 -0
  23. package/bridge/gateway/poller.js +505 -0
  24. package/bridge/gateway/tool-discovery.d.ts +25 -0
  25. package/bridge/gateway/tool-discovery.js +198 -0
  26. package/bridge/index.d.ts +2 -0
  27. package/bridge/index.js +253 -0
  28. package/bridge/logger.d.ts +2 -0
  29. package/bridge/logger.js +2 -0
  30. package/bridge/provider.d.ts +156 -0
  31. package/bridge/provider.js +2 -0
  32. package/bridge/providers/emergency-commands.d.ts +54 -0
  33. package/bridge/providers/emergency-commands.js +235 -0
  34. package/bridge/providers/gateway.d.ts +322 -0
  35. package/bridge/providers/gateway.js +2302 -0
  36. package/bridge/providers/mock.d.ts +37 -0
  37. package/bridge/providers/mock.js +385 -0
  38. package/bridge/providers/onboarding-commands.d.ts +83 -0
  39. package/bridge/providers/onboarding-commands.js +213 -0
  40. package/bridge/providers/risk-calculator.d.ts +96 -0
  41. package/bridge/providers/risk-calculator.js +369 -0
  42. package/bridge/setup.d.ts +32 -0
  43. package/bridge/setup.js +226 -0
  44. package/bridge/types.d.ts +584 -0
  45. package/bridge/types.js +50 -0
  46. package/bridge/utils/reconnect.d.ts +6 -0
  47. package/bridge/utils/reconnect.js +6 -0
  48. package/bridge/utils/skill-signing.d.ts +51 -0
  49. package/bridge/utils/skill-signing.js +138 -0
  50. package/bridge/utils/skill-version.d.ts +17 -0
  51. package/bridge/utils/skill-version.js +74 -0
  52. package/ccxt/binance-ban-gate.d.ts +47 -0
  53. package/ccxt/binance-ban-gate.js +409 -0
  54. package/ccxt/binance-private.d.ts +325 -0
  55. package/ccxt/binance-private.js +1415 -0
  56. package/ccxt/binance-public.d.ts +18 -0
  57. package/ccxt/binance-public.js +147 -0
  58. package/config/agent-config-client.d.ts +55 -0
  59. package/config/agent-config-client.js +145 -0
  60. package/config/agent-config-poller.d.ts +25 -0
  61. package/config/agent-config-poller.js +100 -0
  62. package/config/brackets-config.d.ts +22 -0
  63. package/config/brackets-config.js +58 -0
  64. package/config/gate-store.d.ts +18 -0
  65. package/config/gate-store.js +61 -0
  66. package/config/plugin-config-io.d.ts +181 -0
  67. package/config/plugin-config-io.js +84 -0
  68. package/config/position-review-config.d.ts +35 -0
  69. package/config/position-review-config.js +105 -0
  70. package/config/tool-gate.d.ts +53 -0
  71. package/config/tool-gate.js +125 -0
  72. package/config/user-data-stream-config.d.ts +85 -0
  73. package/config/user-data-stream-config.js +224 -0
  74. package/connector-supervisor.d.ts +36 -0
  75. package/connector-supervisor.js +149 -0
  76. package/exchange-adapter.d.ts +49 -0
  77. package/exchange-adapter.js +4 -0
  78. package/index.d.ts +30 -0
  79. package/index.js +2030 -0
  80. package/ingest/pending-entry-metadata.d.ts +52 -0
  81. package/ingest/pending-entry-metadata.js +182 -0
  82. package/ingest/position-auto-capture.d.ts +98 -0
  83. package/ingest/position-auto-capture.js +394 -0
  84. package/ingest/position-decisions-client.d.ts +318 -0
  85. package/ingest/position-decisions-client.js +296 -0
  86. package/ingest/reconcile-db-vs-exchange.d.ts +13 -0
  87. package/ingest/reconcile-db-vs-exchange.js +114 -0
  88. package/ingest/reconciler-cleanup.d.ts +37 -0
  89. package/ingest/reconciler-cleanup.js +147 -0
  90. package/ingest/rest-gap-filler.d.ts +191 -0
  91. package/ingest/rest-gap-filler.js +565 -0
  92. package/ingest/touched-symbols-store.d.ts +25 -0
  93. package/ingest/touched-symbols-store.js +96 -0
  94. package/ingest/trade-store-client.d.ts +40 -0
  95. package/ingest/trade-store-client.js +125 -0
  96. package/ingest/ws-ingest.d.ts +43 -0
  97. package/ingest/ws-ingest.js +126 -0
  98. package/learning/setup-family.d.ts +21 -0
  99. package/learning/setup-family.js +103 -0
  100. package/lifecycle/install-signal-handlers.d.ts +33 -0
  101. package/lifecycle/install-signal-handlers.js +112 -0
  102. package/lifecycle/shutdown-coordinator.d.ts +43 -0
  103. package/lifecycle/shutdown-coordinator.js +131 -0
  104. package/live/bracket-id.d.ts +18 -0
  105. package/live/bracket-id.js +81 -0
  106. package/live/bracket-ledger.d.ts +54 -0
  107. package/live/bracket-ledger.js +267 -0
  108. package/live/bracket-manager.d.ts +82 -0
  109. package/live/bracket-manager.js +478 -0
  110. package/live/bracket-params.d.ts +22 -0
  111. package/live/bracket-params.js +124 -0
  112. package/live/bracket-reconciler.d.ts +95 -0
  113. package/live/bracket-reconciler.js +573 -0
  114. package/live/bracket-types.d.ts +102 -0
  115. package/live/bracket-types.js +8 -0
  116. package/live/deposit-tracker.d.ts +62 -0
  117. package/live/deposit-tracker.js +97 -0
  118. package/live/emergency-controls.d.ts +32 -0
  119. package/live/emergency-controls.js +226 -0
  120. package/live/exchange-errors.d.ts +12 -0
  121. package/live/exchange-errors.js +130 -0
  122. package/live/exchange-info-cache.d.ts +35 -0
  123. package/live/exchange-info-cache.js +119 -0
  124. package/live/fact-subscriber.d.ts +78 -0
  125. package/live/fact-subscriber.js +182 -0
  126. package/live/intent-journal.d.ts +42 -0
  127. package/live/intent-journal.js +122 -0
  128. package/live/listen-key-manager.d.ts +70 -0
  129. package/live/listen-key-manager.js +169 -0
  130. package/live/live-adapter.d.ts +264 -0
  131. package/live/live-adapter.js +1665 -0
  132. package/live/live-balance-enricher.d.ts +32 -0
  133. package/live/live-balance-enricher.js +104 -0
  134. package/live/live-bracket-api.d.ts +13 -0
  135. package/live/live-bracket-api.js +20 -0
  136. package/live/live-state-store.d.ts +194 -0
  137. package/live/live-state-store.js +450 -0
  138. package/live/local-signal-service.d.ts +57 -0
  139. package/live/local-signal-service.js +146 -0
  140. package/live/local-strategy-evaluator.d.ts +62 -0
  141. package/live/local-strategy-evaluator.js +127 -0
  142. package/live/microstructure-assembler.d.ts +54 -0
  143. package/live/microstructure-assembler.js +148 -0
  144. package/live/order-poller.d.ts +29 -0
  145. package/live/order-poller.js +125 -0
  146. package/live/position-state-store.d.ts +83 -0
  147. package/live/position-state-store.js +237 -0
  148. package/live/proposal-decision-listener.d.ts +64 -0
  149. package/live/proposal-decision-listener.js +288 -0
  150. package/live/proposal-manager.d.ts +76 -0
  151. package/live/proposal-manager.js +140 -0
  152. package/live/rate-limiter.d.ts +47 -0
  153. package/live/rate-limiter.js +159 -0
  154. package/live/reconciler.d.ts +39 -0
  155. package/live/reconciler.js +175 -0
  156. package/live/setup-buckets.d.ts +7 -0
  157. package/live/setup-buckets.js +33 -0
  158. package/live/slippage-tracker.d.ts +45 -0
  159. package/live/slippage-tracker.js +78 -0
  160. package/live/stop-watcher.d.ts +34 -0
  161. package/live/stop-watcher.js +158 -0
  162. package/live/user-data-active-probe.d.ts +54 -0
  163. package/live/user-data-active-probe.js +180 -0
  164. package/live/user-data-stream-controller.d.ts +200 -0
  165. package/live/user-data-stream-controller.js +579 -0
  166. package/live/user-data-stream-ws.d.ts +22 -0
  167. package/live/user-data-stream-ws.js +63 -0
  168. package/live/user-data-stream.d.ts +243 -0
  169. package/live/user-data-stream.js +704 -0
  170. package/logger.d.ts +2 -0
  171. package/logger.js +2 -0
  172. package/mfe.d.ts +21 -0
  173. package/mfe.js +68 -0
  174. package/onboarding/mode-ladder.d.ts +1 -0
  175. package/onboarding/mode-ladder.js +3 -0
  176. package/onboarding/runtime.d.ts +71 -0
  177. package/onboarding/runtime.js +153 -0
  178. package/openclaw.plugin.json +94 -0
  179. package/package.json +27 -0
  180. package/paper-adapter.d.ts +24 -0
  181. package/paper-adapter.js +91 -0
  182. package/persistence/state-manager.d.ts +42 -0
  183. package/persistence/state-manager.js +164 -0
  184. package/pinned-plan.d.ts +9 -0
  185. package/pinned-plan.js +23 -0
  186. package/risk/pre-trade-check.d.ts +38 -0
  187. package/risk/pre-trade-check.js +345 -0
  188. package/risk/pre-trade-types.d.ts +60 -0
  189. package/risk/pre-trade-types.js +3 -0
  190. package/scripts/assemble.mjs +114 -0
  191. package/shadow/shadow-tracker.d.ts +36 -0
  192. package/shadow/shadow-tracker.js +151 -0
  193. package/shadow/types.d.ts +42 -0
  194. package/shadow/types.js +20 -0
  195. package/shared/indicators-extended.d.ts +52 -0
  196. package/shared/indicators-extended.js +291 -0
  197. package/shared/indicators.d.ts +15 -0
  198. package/shared/indicators.js +114 -0
  199. package/signals/conditions/registry.d.ts +16 -0
  200. package/signals/conditions/registry.js +1274 -0
  201. package/signals/conditions/types.d.ts +1 -0
  202. package/signals/conditions/types.js +4 -0
  203. package/signals/direction-rules.d.ts +3 -0
  204. package/signals/direction-rules.js +24 -0
  205. package/signals/entry-rules.d.ts +6 -0
  206. package/signals/entry-rules.js +33 -0
  207. package/signals/serialize-context.d.ts +4 -0
  208. package/signals/serialize-context.js +39 -0
  209. package/signals/stop-rules.d.ts +3 -0
  210. package/signals/stop-rules.js +48 -0
  211. package/signals/strategy-adapter.d.ts +14 -0
  212. package/signals/strategy-adapter.js +122 -0
  213. package/signals/types.d.ts +1 -0
  214. package/signals/types.js +8 -0
  215. package/simulator/exchange-simulator.d.ts +93 -0
  216. package/simulator/exchange-simulator.js +684 -0
  217. package/simulator/fill-engine.d.ts +53 -0
  218. package/simulator/fill-engine.js +276 -0
  219. package/simulator/paper-market-feed.d.ts +26 -0
  220. package/simulator/paper-market-feed.js +104 -0
  221. package/simulator/realistic-fills.d.ts +59 -0
  222. package/simulator/realistic-fills.js +175 -0
  223. package/simulator/types.d.ts +219 -0
  224. package/simulator/types.js +43 -0
  225. package/skills/reefclaw/SKILL.md +97 -0
  226. package/strategy/builtin-strategies.d.ts +2 -0
  227. package/strategy/builtin-strategies.js +109 -0
  228. package/strategy/condition-registry.d.ts +3 -0
  229. package/strategy/condition-registry.js +153 -0
  230. package/strategy/evaluator.d.ts +67 -0
  231. package/strategy/evaluator.js +93 -0
  232. package/tools/assessment-validation.d.ts +118 -0
  233. package/tools/assessment-validation.js +415 -0
  234. package/tools/attach-brackets.d.ts +34 -0
  235. package/tools/attach-brackets.js +363 -0
  236. package/tools/audit-bracket-protection.d.ts +49 -0
  237. package/tools/audit-bracket-protection.js +527 -0
  238. package/tools/cancel-all-orders.d.ts +7 -0
  239. package/tools/cancel-all-orders.js +5 -0
  240. package/tools/cancel-order.d.ts +10 -0
  241. package/tools/cancel-order.js +14 -0
  242. package/tools/check-position-health.d.ts +46 -0
  243. package/tools/check-position-health.js +194 -0
  244. package/tools/clear-exchange-credentials.d.ts +24 -0
  245. package/tools/clear-exchange-credentials.js +70 -0
  246. package/tools/close-position.d.ts +22 -0
  247. package/tools/close-position.js +449 -0
  248. package/tools/create-order.d.ts +54 -0
  249. package/tools/create-order.js +338 -0
  250. package/tools/exit-gate.d.ts +58 -0
  251. package/tools/exit-gate.js +162 -0
  252. package/tools/fetch-balance.d.ts +5 -0
  253. package/tools/fetch-balance.js +4 -0
  254. package/tools/fetch-ohlcv.d.ts +11 -0
  255. package/tools/fetch-ohlcv.js +8 -0
  256. package/tools/fetch-open-orders.d.ts +7 -0
  257. package/tools/fetch-open-orders.js +4 -0
  258. package/tools/fetch-positions.d.ts +7 -0
  259. package/tools/fetch-positions.js +4 -0
  260. package/tools/fetch-ticker.d.ts +11 -0
  261. package/tools/fetch-ticker.js +5 -0
  262. package/tools/get-agent-profile.d.ts +4 -0
  263. package/tools/get-agent-profile.js +6 -0
  264. package/tools/get-analytics.d.ts +6 -0
  265. package/tools/get-analytics.js +7 -0
  266. package/tools/get-backtest.d.ts +12 -0
  267. package/tools/get-backtest.js +91 -0
  268. package/tools/get-basis.d.ts +7 -0
  269. package/tools/get-basis.js +7 -0
  270. package/tools/get-bracket-config.d.ts +11 -0
  271. package/tools/get-bracket-config.js +24 -0
  272. package/tools/get-cascade-risk.d.ts +7 -0
  273. package/tools/get-cascade-risk.js +8 -0
  274. package/tools/get-crypto-metrics.d.ts +18 -0
  275. package/tools/get-crypto-metrics.js +45 -0
  276. package/tools/get-cvd.d.ts +6 -0
  277. package/tools/get-cvd.js +6 -0
  278. package/tools/get-divergences.d.ts +6 -0
  279. package/tools/get-divergences.js +6 -0
  280. package/tools/get-funding-context.d.ts +6 -0
  281. package/tools/get-funding-context.js +16 -0
  282. package/tools/get-liquidation-levels.d.ts +7 -0
  283. package/tools/get-liquidation-levels.js +7 -0
  284. package/tools/get-liquidation-pulse.d.ts +9 -0
  285. package/tools/get-liquidation-pulse.js +22 -0
  286. package/tools/get-market-breadth.d.ts +6 -0
  287. package/tools/get-market-breadth.js +8 -0
  288. package/tools/get-market-intel.d.ts +19 -0
  289. package/tools/get-market-intel.js +116 -0
  290. package/tools/get-market-structure.d.ts +47 -0
  291. package/tools/get-market-structure.js +198 -0
  292. package/tools/get-my-mined-patterns.d.ts +20 -0
  293. package/tools/get-my-mined-patterns.js +61 -0
  294. package/tools/get-my-proposed-learnings.d.ts +20 -0
  295. package/tools/get-my-proposed-learnings.js +55 -0
  296. package/tools/get-my-recent-reviews.d.ts +22 -0
  297. package/tools/get-my-recent-reviews.js +66 -0
  298. package/tools/get-orderbook.d.ts +21 -0
  299. package/tools/get-orderbook.js +32 -0
  300. package/tools/get-pattern-scan.d.ts +7 -0
  301. package/tools/get-pattern-scan.js +8 -0
  302. package/tools/get-regime.d.ts +6 -0
  303. package/tools/get-regime.js +7 -0
  304. package/tools/get-relevant-learnings.d.ts +21 -0
  305. package/tools/get-relevant-learnings.js +65 -0
  306. package/tools/get-resting-liquidity.d.ts +6 -0
  307. package/tools/get-resting-liquidity.js +11 -0
  308. package/tools/get-risk-scenario.d.ts +29 -0
  309. package/tools/get-risk-scenario.js +47 -0
  310. package/tools/get-risk-summary.d.ts +51 -0
  311. package/tools/get-risk-summary.js +118 -0
  312. package/tools/get-sentiment.d.ts +4 -0
  313. package/tools/get-sentiment.js +6 -0
  314. package/tools/get-session-review.d.ts +7 -0
  315. package/tools/get-session-review.js +8 -0
  316. package/tools/get-setup-detail.d.ts +7 -0
  317. package/tools/get-setup-detail.js +303 -0
  318. package/tools/get-signals.d.ts +15 -0
  319. package/tools/get-signals.js +54 -0
  320. package/tools/get-sizing.d.ts +6 -0
  321. package/tools/get-sizing.js +6 -0
  322. package/tools/get-trade-feedback.d.ts +7 -0
  323. package/tools/get-trade-feedback.js +8 -0
  324. package/tools/get-trade-flow.d.ts +7 -0
  325. package/tools/get-trade-flow.js +7 -0
  326. package/tools/get-volume-analysis.d.ts +21 -0
  327. package/tools/get-volume-analysis.js +74 -0
  328. package/tools/get-volume-profile.d.ts +7 -0
  329. package/tools/get-volume-profile.js +7 -0
  330. package/tools/helpers.d.ts +25 -0
  331. package/tools/helpers.js +38 -0
  332. package/tools/intel-api.d.ts +14 -0
  333. package/tools/intel-api.js +52 -0
  334. package/tools/intel-cache.d.ts +25 -0
  335. package/tools/intel-cache.js +133 -0
  336. package/tools/list-strategies.d.ts +7 -0
  337. package/tools/list-strategies.js +6 -0
  338. package/tools/modify-stop.d.ts +17 -0
  339. package/tools/modify-stop.js +81 -0
  340. package/tools/modify-target.d.ts +17 -0
  341. package/tools/modify-target.js +71 -0
  342. package/tools/propose-learning.d.ts +22 -0
  343. package/tools/propose-learning.js +65 -0
  344. package/tools/query-review-outcomes.d.ts +30 -0
  345. package/tools/query-review-outcomes.js +64 -0
  346. package/tools/query-trades.d.ts +21 -0
  347. package/tools/query-trades.js +37 -0
  348. package/tools/record-position-reviews.d.ts +38 -0
  349. package/tools/record-position-reviews.js +147 -0
  350. package/tools/save-strategy.d.ts +16 -0
  351. package/tools/save-strategy.js +46 -0
  352. package/tools/scan-pairs.d.ts +18 -0
  353. package/tools/scan-pairs.js +220 -0
  354. package/tools/score-setup.d.ts +31 -0
  355. package/tools/score-setup.js +268 -0
  356. package/tools/set-bracket-requirement.d.ts +18 -0
  357. package/tools/set-bracket-requirement.js +81 -0
  358. package/tools/set-exchange-credentials.d.ts +25 -0
  359. package/tools/set-exchange-credentials.js +80 -0
  360. package/tools/set-trading-mode.d.ts +26 -0
  361. package/tools/set-trading-mode.js +135 -0
  362. package/tools/test-exchange-credentials.d.ts +16 -0
  363. package/tools/test-exchange-credentials.js +100 -0
  364. package/tools/toggle-strategy.d.ts +8 -0
  365. package/tools/toggle-strategy.js +8 -0
  366. package/trading-params-cache.d.ts +26 -0
  367. package/trading-params-cache.js +52 -0
  368. package/types.d.ts +110 -0
  369. package/types.js +7 -0
  370. package/util/plugin-paths.d.ts +3 -0
  371. package/util/plugin-paths.js +15 -0
@@ -0,0 +1,114 @@
1
+ // Assemble the publishable @reefclaw/openclaw-plugin package tree.
2
+ //
3
+ // This is the npm-channel distribution of the plugin — installable with ZERO
4
+ // terminal access via OpenClaw's owner chat command:
5
+ // /plugins install npm:@reefclaw/openclaw-plugin
6
+ // (requires commands.plugins: true; the install auto-restarts the gateway).
7
+ //
8
+ // Layout produced IN THIS DIRECTORY (package root = plugin dist root, because
9
+ // openclaw.extensions points at ./index.js):
10
+ // index.js + rest of plugin/dist — the plugin, at package root
11
+ // openclaw.plugin.json — manifest + `skills` declaration (npm
12
+ // package only — the npx-installer copy
13
+ // has no skills/ subdir)
14
+ // bridge/ — the connector (skill dist); the plugin's
15
+ // connector-supervisor auto-starts it when
16
+ // bundled (see connector-supervisor.ts)
17
+ // skills/reefclaw/SKILL.md — the thin bootstrap skill (full playbook
18
+ // arrives token-gated post-connect)
19
+ // Runtime deps (ccxt/ws/json5/@reefclaw/shared) are REAL npm dependencies —
20
+ // OpenClaw's plugin installer runs the package manager, unlike gateway boot.
21
+
22
+ import { cpSync, existsSync, rmSync, mkdirSync, readdirSync, statSync, readFileSync, writeFileSync } from 'node:fs';
23
+ import { join, dirname } from 'node:path';
24
+ import { fileURLToPath } from 'node:url';
25
+
26
+ const here = dirname(fileURLToPath(import.meta.url)); // plugin-package/scripts
27
+ const pkgRoot = join(here, '..');
28
+ const repoRoot = join(pkgRoot, '..');
29
+
30
+ function skip(name) {
31
+ return (
32
+ name === '__tests__' ||
33
+ name.endsWith('.test.js') ||
34
+ name.endsWith('.test.d.ts') ||
35
+ name.endsWith('.map') ||
36
+ name.endsWith('.tsbuildinfo')
37
+ );
38
+ }
39
+
40
+ function copyTree(from, to) {
41
+ mkdirSync(to, { recursive: true });
42
+ for (const entry of readdirSync(from)) {
43
+ if (skip(entry)) continue;
44
+ const s = join(from, entry);
45
+ const d = join(to, entry);
46
+ if (statSync(s).isDirectory()) copyTree(s, d);
47
+ else cpSync(s, d);
48
+ }
49
+ }
50
+
51
+ // Clean previous assembly output (everything except the package sources).
52
+ const KEEP = new Set(['package.json', 'scripts', 'README.md', 'node_modules', '.gitignore']);
53
+ for (const entry of readdirSync(pkgRoot)) {
54
+ if (!KEEP.has(entry)) rmSync(join(pkgRoot, entry), { recursive: true, force: true });
55
+ }
56
+
57
+ let missing = 0;
58
+
59
+ // 1. Plugin dist at package root.
60
+ const pluginDist = join(repoRoot, 'plugin', 'dist');
61
+ if (!existsSync(pluginDist)) {
62
+ console.error('[assemble] missing plugin/dist — build the plugin first.');
63
+ missing += 1;
64
+ } else {
65
+ copyTree(pluginDist, pkgRoot);
66
+ console.log('[assemble] plugin/dist -> package root');
67
+ }
68
+
69
+ // 2. Manifest, with the `skills` declaration injected (npm package only).
70
+ const manifestSrc = join(repoRoot, 'plugin', 'openclaw.plugin.json');
71
+ if (!existsSync(manifestSrc)) {
72
+ console.error('[assemble] missing plugin/openclaw.plugin.json.');
73
+ missing += 1;
74
+ } else {
75
+ const manifest = JSON.parse(readFileSync(manifestSrc, 'utf-8'));
76
+ manifest.skills = ['./skills'];
77
+ writeFileSync(join(pkgRoot, 'openclaw.plugin.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf-8');
78
+ console.log(`[assemble] manifest (+skills decl), ${manifest.contracts?.tools?.length ?? 0} contract tools`);
79
+ }
80
+
81
+ // 3. The connector, bundled — this is what flips the supervisor's auto-start.
82
+ const skillDist = join(repoRoot, 'skill', 'dist');
83
+ if (!existsSync(skillDist)) {
84
+ console.error('[assemble] missing skill/dist — build the skill first.');
85
+ missing += 1;
86
+ } else {
87
+ copyTree(skillDist, join(pkgRoot, 'bridge'));
88
+ console.log('[assemble] skill/dist -> bridge/');
89
+ }
90
+
91
+ // 4. Bootstrap skill (config schema + connect instructions only — never the
92
+ // full trading playbook; that stays token-gated behind the webapp).
93
+ const bootstrap = join(repoRoot, 'skill', 'SKILL-bootstrap.md');
94
+ if (!existsSync(bootstrap)) {
95
+ console.error('[assemble] missing skill/SKILL-bootstrap.md.');
96
+ missing += 1;
97
+ } else {
98
+ const size = statSync(bootstrap).size;
99
+ if (size > 20_000) {
100
+ console.error(`[assemble] bootstrap is ${size} bytes (>20KB) — is this the FULL SKILL.md? Refusing.`);
101
+ missing += 1;
102
+ } else {
103
+ mkdirSync(join(pkgRoot, 'skills', 'reefclaw'), { recursive: true });
104
+ cpSync(bootstrap, join(pkgRoot, 'skills', 'reefclaw', 'SKILL.md'));
105
+ console.log(`[assemble] bootstrap skill (${size} bytes) -> skills/reefclaw/SKILL.md`);
106
+ }
107
+ }
108
+
109
+ if (missing > 0) {
110
+ console.error(`[assemble] ${missing} input(s) missing — package INCOMPLETE; do not publish.`);
111
+ process.exitCode = 1;
112
+ } else {
113
+ console.log('[assemble] package complete.');
114
+ }
@@ -0,0 +1,36 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { BinancePrivateApi } from '../ccxt/binance-private.js';
3
+ import type { ExchangeSimulator } from '../simulator/exchange-simulator.js';
4
+ import type { ShadowComparison, ShadowMetrics, ShadowConfig } from './types.js';
5
+ /**
6
+ * ShadowTracker hooks into the ExchangeSimulator to compute
7
+ * shadow estimates for every paper fill.
8
+ *
9
+ * Events emitted:
10
+ * - 'shadowComparison': ShadowComparison — after each fill comparison
11
+ */
12
+ export declare class ShadowTracker extends EventEmitter {
13
+ private privateApi;
14
+ private simulator;
15
+ private metrics;
16
+ private config;
17
+ private recentComparisons;
18
+ private active;
19
+ constructor(privateApi: BinancePrivateApi, simulator: ExchangeSimulator, config?: ShadowConfig, existingMetrics?: ShadowMetrics);
20
+ /** Start listening for simulator fill events. */
21
+ start(): void;
22
+ /** Stop listening. */
23
+ stop(): void;
24
+ /** Get current shadow metrics. */
25
+ getMetrics(): ShadowMetrics;
26
+ /** Get recent comparisons. */
27
+ getRecentComparisons(): ShadowComparison[];
28
+ /** Check if shadow mode criteria are met for mode upgrade. */
29
+ isReadyForUpgrade(): {
30
+ ready: boolean;
31
+ reasons: string[];
32
+ };
33
+ private onFill;
34
+ private computeShadowComparison;
35
+ private updateMetrics;
36
+ }
@@ -0,0 +1,151 @@
1
+ // Shadow Tracker — compares paper fills against live exchange estimates.
2
+ // Listens for fill events from the simulator, fetches real order book,
3
+ // computes what the live fill would have been, logs the comparison.
4
+ import { EventEmitter } from 'node:events';
5
+ import { logger } from '../logger.js';
6
+ import { priceToBps } from '../simulator/types.js';
7
+ import { computeBookAwareFillPrice } from '../simulator/realistic-fills.js';
8
+ import { createEmptyShadowMetrics, DEFAULT_SHADOW_CONFIG } from './types.js';
9
+ const TAG = 'shadow-tracker';
10
+ /** Maximum recent comparisons to keep in memory. */
11
+ const MAX_RECENT_COMPARISONS = 100;
12
+ /**
13
+ * ShadowTracker hooks into the ExchangeSimulator to compute
14
+ * shadow estimates for every paper fill.
15
+ *
16
+ * Events emitted:
17
+ * - 'shadowComparison': ShadowComparison — after each fill comparison
18
+ */
19
+ export class ShadowTracker extends EventEmitter {
20
+ privateApi;
21
+ simulator;
22
+ metrics;
23
+ config;
24
+ recentComparisons = [];
25
+ active = false;
26
+ constructor(privateApi, simulator, config, existingMetrics) {
27
+ super();
28
+ this.privateApi = privateApi;
29
+ this.simulator = simulator;
30
+ this.config = config ?? DEFAULT_SHADOW_CONFIG;
31
+ this.metrics = existingMetrics ?? createEmptyShadowMetrics();
32
+ }
33
+ /** Start listening for simulator fill events. */
34
+ start() {
35
+ if (this.active)
36
+ return;
37
+ this.active = true;
38
+ this.simulator.on('fill', this.onFill);
39
+ logger.info(TAG, `Shadow tracker started (${this.metrics.totalShadowTrades} prior comparisons)`);
40
+ }
41
+ /** Stop listening. */
42
+ stop() {
43
+ if (!this.active)
44
+ return;
45
+ this.active = false;
46
+ this.simulator.off('fill', this.onFill);
47
+ logger.info(TAG, 'Shadow tracker stopped');
48
+ }
49
+ /** Get current shadow metrics. */
50
+ getMetrics() {
51
+ return { ...this.metrics };
52
+ }
53
+ /** Get recent comparisons. */
54
+ getRecentComparisons() {
55
+ return [...this.recentComparisons];
56
+ }
57
+ /** Check if shadow mode criteria are met for mode upgrade. */
58
+ isReadyForUpgrade() {
59
+ const reasons = [];
60
+ if (this.metrics.totalShadowTrades < this.config.minTrades) {
61
+ reasons.push(`Need ${this.config.minTrades} shadow trades, have ${this.metrics.totalShadowTrades}`);
62
+ }
63
+ if (this.metrics.tradingDays < this.config.minDays) {
64
+ reasons.push(`Need ${this.config.minDays} trading days, have ${this.metrics.tradingDays}`);
65
+ }
66
+ if (this.metrics.avgDeltaBps > this.config.maxAvgDeltaBps) {
67
+ reasons.push(`Avg delta ${this.metrics.avgDeltaBps.toFixed(2)}bps exceeds max ${this.config.maxAvgDeltaBps}bps`);
68
+ }
69
+ return { ready: reasons.length === 0, reasons };
70
+ }
71
+ // Arrow function to preserve `this` binding when used as event listener
72
+ onFill = (fillData) => {
73
+ // Only compare market order fills (limit orders fill at limit price, no comparison needed)
74
+ if (fillData.type !== 'market')
75
+ return;
76
+ // Fire and forget — shadow comparison is async but doesn't block the fill
77
+ this.computeShadowComparison(fillData).catch(err => {
78
+ logger.warn(TAG, `Shadow comparison failed: ${err instanceof Error ? err.message : String(err)}`);
79
+ });
80
+ };
81
+ async computeShadowComparison(fillData) {
82
+ // Fetch fresh order book from the exchange (authenticated path)
83
+ const liveBook = await this.privateApi.fetchOrderBook(fillData.symbol, 20);
84
+ let shadowPrice;
85
+ let bookDepthUsed = 0;
86
+ let bookDepthAvailable = false;
87
+ if (liveBook && liveBook.asks.length > 0 && liveBook.bids.length > 0) {
88
+ // Walk the live book to compute shadow VWAP
89
+ const { vwap, levelsConsumed } = computeBookAwareFillPrice(fillData.side, fillData.amount, liveBook);
90
+ shadowPrice = vwap;
91
+ bookDepthUsed = levelsConsumed;
92
+ bookDepthAvailable = true;
93
+ }
94
+ else {
95
+ // No live book available — use paper fill as shadow estimate
96
+ shadowPrice = fillData.fillPrice;
97
+ logger.warn(TAG, `No live order book for ${fillData.symbol} — shadow estimate equals paper`);
98
+ }
99
+ // Compute shadow fee (same taker rate as paper for fair comparison)
100
+ const simConfig = this.simulator.getSimulationConfig();
101
+ const shadowFee = fillData.amount * shadowPrice * simConfig.fees.takerRate;
102
+ // Delta: positive = live would be worse (pay more for buy, receive less for sell)
103
+ const deltaBps = priceToBps(shadowPrice, fillData.fillPrice);
104
+ const comparison = {
105
+ orderId: fillData.orderId,
106
+ symbol: fillData.symbol,
107
+ side: fillData.side,
108
+ type: fillData.type,
109
+ amount: fillData.amount,
110
+ paperFillPrice: fillData.fillPrice,
111
+ shadowEstimatePrice: shadowPrice,
112
+ deltaBps,
113
+ paperFee: fillData.fee,
114
+ shadowEstimateFee: shadowFee,
115
+ bookDepthUsed,
116
+ bookDepthAvailable,
117
+ timestamp: new Date().toISOString(),
118
+ };
119
+ // Update metrics
120
+ this.updateMetrics(comparison);
121
+ // Store recent comparison (match webapp slice pattern — slice instead of shift)
122
+ this.recentComparisons = [
123
+ ...this.recentComparisons.slice(-(MAX_RECENT_COMPARISONS - 1)),
124
+ comparison,
125
+ ];
126
+ // Emit event for skill/bridge pipeline
127
+ this.emit('shadowComparison', comparison);
128
+ logger.info(TAG, `Shadow comparison: ${fillData.side} ${fillData.amount} ${fillData.symbol}` +
129
+ ` | Paper: ${fillData.fillPrice.toFixed(2)} | Shadow: ${shadowPrice.toFixed(2)}` +
130
+ ` | Delta: ${deltaBps.toFixed(2)}bps` +
131
+ ` | Book: ${bookDepthAvailable ? `${bookDepthUsed} levels` : 'unavailable'}`);
132
+ }
133
+ updateMetrics(comparison) {
134
+ const m = this.metrics;
135
+ m.totalShadowTrades++;
136
+ const absDelta = Math.abs(comparison.deltaBps);
137
+ m.totalDeltaBpsSum += absDelta;
138
+ m.avgDeltaBps = m.totalDeltaBpsSum / m.totalShadowTrades;
139
+ if (absDelta > m.worstDeltaBps) {
140
+ m.worstDeltaBps = absDelta;
141
+ }
142
+ m.paperTotalFees += comparison.paperFee;
143
+ m.shadowTotalFees += comparison.shadowEstimateFee;
144
+ // Track trading days
145
+ const today = comparison.timestamp.slice(0, 10);
146
+ if (today !== m.lastTradeDate) {
147
+ m.tradingDays++;
148
+ m.lastTradeDate = today;
149
+ }
150
+ }
151
+ }
@@ -0,0 +1,42 @@
1
+ import type { TradingMode } from '../types.js';
2
+ export type { TradingMode };
3
+ /** A single shadow comparison record: paper fill vs live estimate. */
4
+ export interface ShadowComparison {
5
+ orderId: string;
6
+ symbol: string;
7
+ side: 'buy' | 'sell';
8
+ type: 'market' | 'limit';
9
+ amount: number;
10
+ paperFillPrice: number;
11
+ shadowEstimatePrice: number;
12
+ deltaBps: number;
13
+ paperFee: number;
14
+ shadowEstimateFee: number;
15
+ bookDepthUsed: number;
16
+ bookDepthAvailable: boolean;
17
+ timestamp: string;
18
+ }
19
+ /** Aggregate shadow metrics across all shadow comparisons. */
20
+ export interface ShadowMetrics {
21
+ totalShadowTrades: number;
22
+ avgDeltaBps: number;
23
+ worstDeltaBps: number;
24
+ totalDeltaBpsSum: number;
25
+ paperTotalFees: number;
26
+ shadowTotalFees: number;
27
+ startedAt: string;
28
+ tradingDays: number;
29
+ lastTradeDate: string;
30
+ }
31
+ /** Shadow mode configuration thresholds. */
32
+ export interface ShadowConfig {
33
+ /** Minimum shadow trades before allowing mode upgrade (default: 50) */
34
+ minTrades: number;
35
+ /** Minimum days in shadow mode (default: 7) */
36
+ minDays: number;
37
+ /** Max acceptable average delta in bps (default: 5) */
38
+ maxAvgDeltaBps: number;
39
+ }
40
+ export declare const DEFAULT_SHADOW_CONFIG: ShadowConfig;
41
+ /** Create empty shadow metrics. */
42
+ export declare function createEmptyShadowMetrics(): ShadowMetrics;
@@ -0,0 +1,20 @@
1
+ // Shadow mode types — tracking paper vs live fill comparison.
2
+ export const DEFAULT_SHADOW_CONFIG = {
3
+ minTrades: 50,
4
+ minDays: 7,
5
+ maxAvgDeltaBps: 5,
6
+ };
7
+ /** Create empty shadow metrics. */
8
+ export function createEmptyShadowMetrics() {
9
+ return {
10
+ totalShadowTrades: 0,
11
+ avgDeltaBps: 0,
12
+ worstDeltaBps: 0,
13
+ totalDeltaBpsSum: 0,
14
+ paperTotalFees: 0,
15
+ shadowTotalFees: 0,
16
+ startedAt: new Date().toISOString(),
17
+ tradingDays: 0,
18
+ lastTradeDate: '',
19
+ };
20
+ }
@@ -0,0 +1,52 @@
1
+ export interface OhlcvInput {
2
+ open: number;
3
+ high: number;
4
+ low: number;
5
+ close: number;
6
+ volume: number;
7
+ }
8
+ export interface MACDResult {
9
+ line: number;
10
+ signal: number;
11
+ histogram: number;
12
+ crossover: 'bullish' | 'bearish' | 'none';
13
+ }
14
+ export interface BollingerResult {
15
+ upper: number;
16
+ middle: number;
17
+ lower: number;
18
+ bandwidth: number;
19
+ percentB: number;
20
+ }
21
+ export interface StochRSIResult {
22
+ k: number;
23
+ d: number;
24
+ }
25
+ export interface IchimokuResult {
26
+ tenkan: number;
27
+ kijun: number;
28
+ senkouA: number;
29
+ senkouB: number;
30
+ chikou: number;
31
+ cloudPosition: 'above' | 'below' | 'inside';
32
+ }
33
+ export interface SupertrendResult {
34
+ value: number;
35
+ direction: 'bullish' | 'bearish';
36
+ }
37
+ export declare function computeMACD(closes: number[], fast?: number, slow?: number, signal?: number): MACDResult;
38
+ export declare function computeBollingerBands(closes: number[], period?: number, stdDev?: number): BollingerResult;
39
+ export declare function computeVWAP(bars: OhlcvInput[]): number;
40
+ export declare function computeStochRSI(closes: number[], rsiPeriod?: number, stochPeriod?: number, kSmooth?: number, dSmooth?: number): StochRSIResult;
41
+ export declare function computeADX(highs: number[], lows: number[], closes: number[], period?: number): {
42
+ adx: number;
43
+ plusDI: number;
44
+ minusDI: number;
45
+ };
46
+ export declare function computeIchimoku(highs: number[], lows: number[], closes: number[], tenkanPeriod?: number, kijunPeriod?: number, senkouBPeriod?: number): IchimokuResult;
47
+ export declare function computeOBV(closes: number[], volumes: number[]): {
48
+ obv: number;
49
+ slope: 'rising' | 'falling' | 'flat';
50
+ };
51
+ export declare function computeSupertrend(highs: number[], lows: number[], closes: number[], period?: number, multiplier?: number): SupertrendResult;
52
+ export declare function computeWilliamsR(highs: number[], lows: number[], closes: number[], period?: number): number;