@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.
- package/.gitignore +8 -0
- package/audit/mode-transition-audit.d.ts +11 -0
- package/audit/mode-transition-audit.js +29 -0
- package/balance-utils.d.ts +36 -0
- package/balance-utils.js +98 -0
- package/bridge/bridge.d.ts +109 -0
- package/bridge/bridge.js +1036 -0
- package/bridge/config.d.ts +43 -0
- package/bridge/config.js +176 -0
- package/bridge/connector.d.ts +52 -0
- package/bridge/connector.js +293 -0
- package/bridge/event-replay-buffer.d.ts +43 -0
- package/bridge/event-replay-buffer.js +109 -0
- package/bridge/gateway/event-parser.d.ts +209 -0
- package/bridge/gateway/event-parser.js +793 -0
- package/bridge/gateway/gateway-config.d.ts +39 -0
- package/bridge/gateway/gateway-config.js +86 -0
- package/bridge/gateway/gateway-http-client.d.ts +50 -0
- package/bridge/gateway/gateway-http-client.js +165 -0
- package/bridge/gateway/gateway-ws-client.d.ts +116 -0
- package/bridge/gateway/gateway-ws-client.js +417 -0
- package/bridge/gateway/poller.d.ts +146 -0
- package/bridge/gateway/poller.js +505 -0
- package/bridge/gateway/tool-discovery.d.ts +25 -0
- package/bridge/gateway/tool-discovery.js +198 -0
- package/bridge/index.d.ts +2 -0
- package/bridge/index.js +253 -0
- package/bridge/logger.d.ts +2 -0
- package/bridge/logger.js +2 -0
- package/bridge/provider.d.ts +156 -0
- package/bridge/provider.js +2 -0
- package/bridge/providers/emergency-commands.d.ts +54 -0
- package/bridge/providers/emergency-commands.js +235 -0
- package/bridge/providers/gateway.d.ts +322 -0
- package/bridge/providers/gateway.js +2302 -0
- package/bridge/providers/mock.d.ts +37 -0
- package/bridge/providers/mock.js +385 -0
- package/bridge/providers/onboarding-commands.d.ts +83 -0
- package/bridge/providers/onboarding-commands.js +213 -0
- package/bridge/providers/risk-calculator.d.ts +96 -0
- package/bridge/providers/risk-calculator.js +369 -0
- package/bridge/setup.d.ts +32 -0
- package/bridge/setup.js +226 -0
- package/bridge/types.d.ts +584 -0
- package/bridge/types.js +50 -0
- package/bridge/utils/reconnect.d.ts +6 -0
- package/bridge/utils/reconnect.js +6 -0
- package/bridge/utils/skill-signing.d.ts +51 -0
- package/bridge/utils/skill-signing.js +138 -0
- package/bridge/utils/skill-version.d.ts +17 -0
- package/bridge/utils/skill-version.js +74 -0
- package/ccxt/binance-ban-gate.d.ts +47 -0
- package/ccxt/binance-ban-gate.js +409 -0
- package/ccxt/binance-private.d.ts +325 -0
- package/ccxt/binance-private.js +1415 -0
- package/ccxt/binance-public.d.ts +18 -0
- package/ccxt/binance-public.js +147 -0
- package/config/agent-config-client.d.ts +55 -0
- package/config/agent-config-client.js +145 -0
- package/config/agent-config-poller.d.ts +25 -0
- package/config/agent-config-poller.js +100 -0
- package/config/brackets-config.d.ts +22 -0
- package/config/brackets-config.js +58 -0
- package/config/gate-store.d.ts +18 -0
- package/config/gate-store.js +61 -0
- package/config/plugin-config-io.d.ts +181 -0
- package/config/plugin-config-io.js +84 -0
- package/config/position-review-config.d.ts +35 -0
- package/config/position-review-config.js +105 -0
- package/config/tool-gate.d.ts +53 -0
- package/config/tool-gate.js +125 -0
- package/config/user-data-stream-config.d.ts +85 -0
- package/config/user-data-stream-config.js +224 -0
- package/connector-supervisor.d.ts +36 -0
- package/connector-supervisor.js +149 -0
- package/exchange-adapter.d.ts +49 -0
- package/exchange-adapter.js +4 -0
- package/index.d.ts +30 -0
- package/index.js +2030 -0
- package/ingest/pending-entry-metadata.d.ts +52 -0
- package/ingest/pending-entry-metadata.js +182 -0
- package/ingest/position-auto-capture.d.ts +98 -0
- package/ingest/position-auto-capture.js +394 -0
- package/ingest/position-decisions-client.d.ts +318 -0
- package/ingest/position-decisions-client.js +296 -0
- package/ingest/reconcile-db-vs-exchange.d.ts +13 -0
- package/ingest/reconcile-db-vs-exchange.js +114 -0
- package/ingest/reconciler-cleanup.d.ts +37 -0
- package/ingest/reconciler-cleanup.js +147 -0
- package/ingest/rest-gap-filler.d.ts +191 -0
- package/ingest/rest-gap-filler.js +565 -0
- package/ingest/touched-symbols-store.d.ts +25 -0
- package/ingest/touched-symbols-store.js +96 -0
- package/ingest/trade-store-client.d.ts +40 -0
- package/ingest/trade-store-client.js +125 -0
- package/ingest/ws-ingest.d.ts +43 -0
- package/ingest/ws-ingest.js +126 -0
- package/learning/setup-family.d.ts +21 -0
- package/learning/setup-family.js +103 -0
- package/lifecycle/install-signal-handlers.d.ts +33 -0
- package/lifecycle/install-signal-handlers.js +112 -0
- package/lifecycle/shutdown-coordinator.d.ts +43 -0
- package/lifecycle/shutdown-coordinator.js +131 -0
- package/live/bracket-id.d.ts +18 -0
- package/live/bracket-id.js +81 -0
- package/live/bracket-ledger.d.ts +54 -0
- package/live/bracket-ledger.js +267 -0
- package/live/bracket-manager.d.ts +82 -0
- package/live/bracket-manager.js +478 -0
- package/live/bracket-params.d.ts +22 -0
- package/live/bracket-params.js +124 -0
- package/live/bracket-reconciler.d.ts +95 -0
- package/live/bracket-reconciler.js +573 -0
- package/live/bracket-types.d.ts +102 -0
- package/live/bracket-types.js +8 -0
- package/live/deposit-tracker.d.ts +62 -0
- package/live/deposit-tracker.js +97 -0
- package/live/emergency-controls.d.ts +32 -0
- package/live/emergency-controls.js +226 -0
- package/live/exchange-errors.d.ts +12 -0
- package/live/exchange-errors.js +130 -0
- package/live/exchange-info-cache.d.ts +35 -0
- package/live/exchange-info-cache.js +119 -0
- package/live/fact-subscriber.d.ts +78 -0
- package/live/fact-subscriber.js +182 -0
- package/live/intent-journal.d.ts +42 -0
- package/live/intent-journal.js +122 -0
- package/live/listen-key-manager.d.ts +70 -0
- package/live/listen-key-manager.js +169 -0
- package/live/live-adapter.d.ts +264 -0
- package/live/live-adapter.js +1665 -0
- package/live/live-balance-enricher.d.ts +32 -0
- package/live/live-balance-enricher.js +104 -0
- package/live/live-bracket-api.d.ts +13 -0
- package/live/live-bracket-api.js +20 -0
- package/live/live-state-store.d.ts +194 -0
- package/live/live-state-store.js +450 -0
- package/live/local-signal-service.d.ts +57 -0
- package/live/local-signal-service.js +146 -0
- package/live/local-strategy-evaluator.d.ts +62 -0
- package/live/local-strategy-evaluator.js +127 -0
- package/live/microstructure-assembler.d.ts +54 -0
- package/live/microstructure-assembler.js +148 -0
- package/live/order-poller.d.ts +29 -0
- package/live/order-poller.js +125 -0
- package/live/position-state-store.d.ts +83 -0
- package/live/position-state-store.js +237 -0
- package/live/proposal-decision-listener.d.ts +64 -0
- package/live/proposal-decision-listener.js +288 -0
- package/live/proposal-manager.d.ts +76 -0
- package/live/proposal-manager.js +140 -0
- package/live/rate-limiter.d.ts +47 -0
- package/live/rate-limiter.js +159 -0
- package/live/reconciler.d.ts +39 -0
- package/live/reconciler.js +175 -0
- package/live/setup-buckets.d.ts +7 -0
- package/live/setup-buckets.js +33 -0
- package/live/slippage-tracker.d.ts +45 -0
- package/live/slippage-tracker.js +78 -0
- package/live/stop-watcher.d.ts +34 -0
- package/live/stop-watcher.js +158 -0
- package/live/user-data-active-probe.d.ts +54 -0
- package/live/user-data-active-probe.js +180 -0
- package/live/user-data-stream-controller.d.ts +200 -0
- package/live/user-data-stream-controller.js +579 -0
- package/live/user-data-stream-ws.d.ts +22 -0
- package/live/user-data-stream-ws.js +63 -0
- package/live/user-data-stream.d.ts +243 -0
- package/live/user-data-stream.js +704 -0
- package/logger.d.ts +2 -0
- package/logger.js +2 -0
- package/mfe.d.ts +21 -0
- package/mfe.js +68 -0
- package/onboarding/mode-ladder.d.ts +1 -0
- package/onboarding/mode-ladder.js +3 -0
- package/onboarding/runtime.d.ts +71 -0
- package/onboarding/runtime.js +153 -0
- package/openclaw.plugin.json +94 -0
- package/package.json +27 -0
- package/paper-adapter.d.ts +24 -0
- package/paper-adapter.js +91 -0
- package/persistence/state-manager.d.ts +42 -0
- package/persistence/state-manager.js +164 -0
- package/pinned-plan.d.ts +9 -0
- package/pinned-plan.js +23 -0
- package/risk/pre-trade-check.d.ts +38 -0
- package/risk/pre-trade-check.js +345 -0
- package/risk/pre-trade-types.d.ts +60 -0
- package/risk/pre-trade-types.js +3 -0
- package/scripts/assemble.mjs +114 -0
- package/shadow/shadow-tracker.d.ts +36 -0
- package/shadow/shadow-tracker.js +151 -0
- package/shadow/types.d.ts +42 -0
- package/shadow/types.js +20 -0
- package/shared/indicators-extended.d.ts +52 -0
- package/shared/indicators-extended.js +291 -0
- package/shared/indicators.d.ts +15 -0
- package/shared/indicators.js +114 -0
- package/signals/conditions/registry.d.ts +16 -0
- package/signals/conditions/registry.js +1274 -0
- package/signals/conditions/types.d.ts +1 -0
- package/signals/conditions/types.js +4 -0
- package/signals/direction-rules.d.ts +3 -0
- package/signals/direction-rules.js +24 -0
- package/signals/entry-rules.d.ts +6 -0
- package/signals/entry-rules.js +33 -0
- package/signals/serialize-context.d.ts +4 -0
- package/signals/serialize-context.js +39 -0
- package/signals/stop-rules.d.ts +3 -0
- package/signals/stop-rules.js +48 -0
- package/signals/strategy-adapter.d.ts +14 -0
- package/signals/strategy-adapter.js +122 -0
- package/signals/types.d.ts +1 -0
- package/signals/types.js +8 -0
- package/simulator/exchange-simulator.d.ts +93 -0
- package/simulator/exchange-simulator.js +684 -0
- package/simulator/fill-engine.d.ts +53 -0
- package/simulator/fill-engine.js +276 -0
- package/simulator/paper-market-feed.d.ts +26 -0
- package/simulator/paper-market-feed.js +104 -0
- package/simulator/realistic-fills.d.ts +59 -0
- package/simulator/realistic-fills.js +175 -0
- package/simulator/types.d.ts +219 -0
- package/simulator/types.js +43 -0
- package/skills/reefclaw/SKILL.md +97 -0
- package/strategy/builtin-strategies.d.ts +2 -0
- package/strategy/builtin-strategies.js +109 -0
- package/strategy/condition-registry.d.ts +3 -0
- package/strategy/condition-registry.js +153 -0
- package/strategy/evaluator.d.ts +67 -0
- package/strategy/evaluator.js +93 -0
- package/tools/assessment-validation.d.ts +118 -0
- package/tools/assessment-validation.js +415 -0
- package/tools/attach-brackets.d.ts +34 -0
- package/tools/attach-brackets.js +363 -0
- package/tools/audit-bracket-protection.d.ts +49 -0
- package/tools/audit-bracket-protection.js +527 -0
- package/tools/cancel-all-orders.d.ts +7 -0
- package/tools/cancel-all-orders.js +5 -0
- package/tools/cancel-order.d.ts +10 -0
- package/tools/cancel-order.js +14 -0
- package/tools/check-position-health.d.ts +46 -0
- package/tools/check-position-health.js +194 -0
- package/tools/clear-exchange-credentials.d.ts +24 -0
- package/tools/clear-exchange-credentials.js +70 -0
- package/tools/close-position.d.ts +22 -0
- package/tools/close-position.js +449 -0
- package/tools/create-order.d.ts +54 -0
- package/tools/create-order.js +338 -0
- package/tools/exit-gate.d.ts +58 -0
- package/tools/exit-gate.js +162 -0
- package/tools/fetch-balance.d.ts +5 -0
- package/tools/fetch-balance.js +4 -0
- package/tools/fetch-ohlcv.d.ts +11 -0
- package/tools/fetch-ohlcv.js +8 -0
- package/tools/fetch-open-orders.d.ts +7 -0
- package/tools/fetch-open-orders.js +4 -0
- package/tools/fetch-positions.d.ts +7 -0
- package/tools/fetch-positions.js +4 -0
- package/tools/fetch-ticker.d.ts +11 -0
- package/tools/fetch-ticker.js +5 -0
- package/tools/get-agent-profile.d.ts +4 -0
- package/tools/get-agent-profile.js +6 -0
- package/tools/get-analytics.d.ts +6 -0
- package/tools/get-analytics.js +7 -0
- package/tools/get-backtest.d.ts +12 -0
- package/tools/get-backtest.js +91 -0
- package/tools/get-basis.d.ts +7 -0
- package/tools/get-basis.js +7 -0
- package/tools/get-bracket-config.d.ts +11 -0
- package/tools/get-bracket-config.js +24 -0
- package/tools/get-cascade-risk.d.ts +7 -0
- package/tools/get-cascade-risk.js +8 -0
- package/tools/get-crypto-metrics.d.ts +18 -0
- package/tools/get-crypto-metrics.js +45 -0
- package/tools/get-cvd.d.ts +6 -0
- package/tools/get-cvd.js +6 -0
- package/tools/get-divergences.d.ts +6 -0
- package/tools/get-divergences.js +6 -0
- package/tools/get-funding-context.d.ts +6 -0
- package/tools/get-funding-context.js +16 -0
- package/tools/get-liquidation-levels.d.ts +7 -0
- package/tools/get-liquidation-levels.js +7 -0
- package/tools/get-liquidation-pulse.d.ts +9 -0
- package/tools/get-liquidation-pulse.js +22 -0
- package/tools/get-market-breadth.d.ts +6 -0
- package/tools/get-market-breadth.js +8 -0
- package/tools/get-market-intel.d.ts +19 -0
- package/tools/get-market-intel.js +116 -0
- package/tools/get-market-structure.d.ts +47 -0
- package/tools/get-market-structure.js +198 -0
- package/tools/get-my-mined-patterns.d.ts +20 -0
- package/tools/get-my-mined-patterns.js +61 -0
- package/tools/get-my-proposed-learnings.d.ts +20 -0
- package/tools/get-my-proposed-learnings.js +55 -0
- package/tools/get-my-recent-reviews.d.ts +22 -0
- package/tools/get-my-recent-reviews.js +66 -0
- package/tools/get-orderbook.d.ts +21 -0
- package/tools/get-orderbook.js +32 -0
- package/tools/get-pattern-scan.d.ts +7 -0
- package/tools/get-pattern-scan.js +8 -0
- package/tools/get-regime.d.ts +6 -0
- package/tools/get-regime.js +7 -0
- package/tools/get-relevant-learnings.d.ts +21 -0
- package/tools/get-relevant-learnings.js +65 -0
- package/tools/get-resting-liquidity.d.ts +6 -0
- package/tools/get-resting-liquidity.js +11 -0
- package/tools/get-risk-scenario.d.ts +29 -0
- package/tools/get-risk-scenario.js +47 -0
- package/tools/get-risk-summary.d.ts +51 -0
- package/tools/get-risk-summary.js +118 -0
- package/tools/get-sentiment.d.ts +4 -0
- package/tools/get-sentiment.js +6 -0
- package/tools/get-session-review.d.ts +7 -0
- package/tools/get-session-review.js +8 -0
- package/tools/get-setup-detail.d.ts +7 -0
- package/tools/get-setup-detail.js +303 -0
- package/tools/get-signals.d.ts +15 -0
- package/tools/get-signals.js +54 -0
- package/tools/get-sizing.d.ts +6 -0
- package/tools/get-sizing.js +6 -0
- package/tools/get-trade-feedback.d.ts +7 -0
- package/tools/get-trade-feedback.js +8 -0
- package/tools/get-trade-flow.d.ts +7 -0
- package/tools/get-trade-flow.js +7 -0
- package/tools/get-volume-analysis.d.ts +21 -0
- package/tools/get-volume-analysis.js +74 -0
- package/tools/get-volume-profile.d.ts +7 -0
- package/tools/get-volume-profile.js +7 -0
- package/tools/helpers.d.ts +25 -0
- package/tools/helpers.js +38 -0
- package/tools/intel-api.d.ts +14 -0
- package/tools/intel-api.js +52 -0
- package/tools/intel-cache.d.ts +25 -0
- package/tools/intel-cache.js +133 -0
- package/tools/list-strategies.d.ts +7 -0
- package/tools/list-strategies.js +6 -0
- package/tools/modify-stop.d.ts +17 -0
- package/tools/modify-stop.js +81 -0
- package/tools/modify-target.d.ts +17 -0
- package/tools/modify-target.js +71 -0
- package/tools/propose-learning.d.ts +22 -0
- package/tools/propose-learning.js +65 -0
- package/tools/query-review-outcomes.d.ts +30 -0
- package/tools/query-review-outcomes.js +64 -0
- package/tools/query-trades.d.ts +21 -0
- package/tools/query-trades.js +37 -0
- package/tools/record-position-reviews.d.ts +38 -0
- package/tools/record-position-reviews.js +147 -0
- package/tools/save-strategy.d.ts +16 -0
- package/tools/save-strategy.js +46 -0
- package/tools/scan-pairs.d.ts +18 -0
- package/tools/scan-pairs.js +220 -0
- package/tools/score-setup.d.ts +31 -0
- package/tools/score-setup.js +268 -0
- package/tools/set-bracket-requirement.d.ts +18 -0
- package/tools/set-bracket-requirement.js +81 -0
- package/tools/set-exchange-credentials.d.ts +25 -0
- package/tools/set-exchange-credentials.js +80 -0
- package/tools/set-trading-mode.d.ts +26 -0
- package/tools/set-trading-mode.js +135 -0
- package/tools/test-exchange-credentials.d.ts +16 -0
- package/tools/test-exchange-credentials.js +100 -0
- package/tools/toggle-strategy.d.ts +8 -0
- package/tools/toggle-strategy.js +8 -0
- package/trading-params-cache.d.ts +26 -0
- package/trading-params-cache.js +52 -0
- package/types.d.ts +110 -0
- package/types.js +7 -0
- package/util/plugin-paths.d.ts +3 -0
- package/util/plugin-paths.js +15 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
import type { EventFrame as _EventFrame } from '@reefclaw/shared';
|
|
2
|
+
export type { Channel, RequestFrame, ResponseFrame, EventFrame, Frame, EmergencyAction } from '@reefclaw/shared';
|
|
3
|
+
export { VALID_CHANNELS, VALID_EMERGENCY_ACTIONS } from '@reefclaw/shared';
|
|
4
|
+
type EventFrame = _EventFrame;
|
|
5
|
+
/** Methods the skill accepts from the relay (browser → skill) */
|
|
6
|
+
export declare const ALLOWED_METHODS: readonly ["emergency.kill", "emergency.flatten", "emergency.pause", "emergency.resume", "reconcile", "chat.send", "skill.update", "close_position", "set_trading_mode", "set_exchange_credentials", "test_exchange_credentials", "clear_exchange_credentials", "get_bracket_config", "set_bracket_requirement"];
|
|
7
|
+
/** Subset of ALLOWED_METHODS that require operator.write scope. The bridge
|
|
8
|
+
* enforces this before dispatching — a session without the scope gets a
|
|
9
|
+
* 403 error. PR2 ships the scope as session-wide (inherited from the Clerk
|
|
10
|
+
* authenticated browser session) because the skill trusts the relay to
|
|
11
|
+
* scope rooms per user; per-method operator gating is defense-in-depth and
|
|
12
|
+
* a hook for PR4 fine-grained roles. */
|
|
13
|
+
export declare const OPERATOR_WRITE_METHODS: ReadonlySet<string>;
|
|
14
|
+
export type AllowedMethod = (typeof ALLOWED_METHODS)[number];
|
|
15
|
+
export interface TickerData {
|
|
16
|
+
symbol: string;
|
|
17
|
+
lastPrice: number;
|
|
18
|
+
bidPrice: number;
|
|
19
|
+
askPrice: number;
|
|
20
|
+
volume24h: number;
|
|
21
|
+
change24h: number;
|
|
22
|
+
change24hPercent: number;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
}
|
|
25
|
+
export interface CandleData {
|
|
26
|
+
symbol: string;
|
|
27
|
+
candle: {
|
|
28
|
+
time: number;
|
|
29
|
+
open: number;
|
|
30
|
+
high: number;
|
|
31
|
+
low: number;
|
|
32
|
+
close: number;
|
|
33
|
+
volume: number;
|
|
34
|
+
};
|
|
35
|
+
timestamp: string;
|
|
36
|
+
}
|
|
37
|
+
export interface OrderData {
|
|
38
|
+
id: string;
|
|
39
|
+
symbol: string;
|
|
40
|
+
side: 'BUY' | 'SELL';
|
|
41
|
+
type: 'MARKET' | 'LIMIT';
|
|
42
|
+
status: string;
|
|
43
|
+
quantity: number;
|
|
44
|
+
filledQuantity: number;
|
|
45
|
+
averageFillPrice: number;
|
|
46
|
+
timeInForce: string;
|
|
47
|
+
createdAt: string;
|
|
48
|
+
updatedAt: string;
|
|
49
|
+
/**
|
|
50
|
+
* True when this order can only REDUCE/CLOSE a position — a protective
|
|
51
|
+
* bracket (STOP_MARKET / TAKE_PROFIT_MARKET, `reduceOnly` or `closePosition`),
|
|
52
|
+
* never a working entry/add. The kill switch preserves these so it never
|
|
53
|
+
* leaves an open position naked. Computed in `mapCcxtOrder`; undefined on
|
|
54
|
+
* paper / legacy paths (treated as a working order → cancellable).
|
|
55
|
+
*/
|
|
56
|
+
protective?: boolean;
|
|
57
|
+
}
|
|
58
|
+
export interface FillData {
|
|
59
|
+
id: string;
|
|
60
|
+
orderId: string;
|
|
61
|
+
symbol: string;
|
|
62
|
+
side: 'BUY' | 'SELL';
|
|
63
|
+
quantity: number;
|
|
64
|
+
price: number;
|
|
65
|
+
expectedPrice: number;
|
|
66
|
+
slippage: number;
|
|
67
|
+
slippageBps: number;
|
|
68
|
+
fee: number;
|
|
69
|
+
feeCurrency: string;
|
|
70
|
+
timestamp: string;
|
|
71
|
+
/**
|
|
72
|
+
* True when the fill reduces (closes / partially trims) a position rather
|
|
73
|
+
* than opens or adds to one. Optional because legacy gateway payloads omit
|
|
74
|
+
* it — webapp degrades gracefully to direction-only rendering when absent.
|
|
75
|
+
*/
|
|
76
|
+
reduceOnly?: boolean;
|
|
77
|
+
}
|
|
78
|
+
export interface OrderUpdatePayload {
|
|
79
|
+
orderId: string;
|
|
80
|
+
status: string;
|
|
81
|
+
order: OrderData;
|
|
82
|
+
fill?: FillData;
|
|
83
|
+
timestamp: string;
|
|
84
|
+
}
|
|
85
|
+
export interface AgentStateData {
|
|
86
|
+
state: {
|
|
87
|
+
mode: 'ACTIVE' | 'PAUSED' | 'STOPPED' | 'ERROR';
|
|
88
|
+
strategy: {
|
|
89
|
+
name: string;
|
|
90
|
+
version: string;
|
|
91
|
+
};
|
|
92
|
+
/** OpenClaw agent display name (identity), resolved from the gateway. Optional:
|
|
93
|
+
* absent on older skills / when the gateway doesn't surface an identity. */
|
|
94
|
+
agentName?: string;
|
|
95
|
+
/** Live LLM model id the agent is running (e.g. "openai-codex/gpt-5.4-mini"),
|
|
96
|
+
* resolved from the gateway. Optional: absent on older skills. */
|
|
97
|
+
model?: string;
|
|
98
|
+
health: {
|
|
99
|
+
uptime: number;
|
|
100
|
+
lastDecision: string;
|
|
101
|
+
lastTrade: string | null;
|
|
102
|
+
errorRate: number;
|
|
103
|
+
thinkingInterval: number;
|
|
104
|
+
/** Gateway WebSocket state — helps diagnose chat delivery failures */
|
|
105
|
+
gatewayWs?: string;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
timestamp: string;
|
|
109
|
+
}
|
|
110
|
+
export interface RiskLimits {
|
|
111
|
+
position: {
|
|
112
|
+
maxPositionSize: number;
|
|
113
|
+
maxOpenPositions: number;
|
|
114
|
+
maxGrossExposure: number;
|
|
115
|
+
maxNetExposure: number;
|
|
116
|
+
};
|
|
117
|
+
loss: {
|
|
118
|
+
maxDailyDrawdown: number;
|
|
119
|
+
maxPerTradeLoss: number;
|
|
120
|
+
maxDailyLoss: number;
|
|
121
|
+
};
|
|
122
|
+
rate: {
|
|
123
|
+
maxOrdersPerMinute: number;
|
|
124
|
+
maxCancelsPerMinute: number;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
export interface RiskUtilization {
|
|
128
|
+
currentPositionSize: Record<string, number>;
|
|
129
|
+
openPositionCount: number;
|
|
130
|
+
grossExposure: number;
|
|
131
|
+
netExposure: number;
|
|
132
|
+
dailyDrawdown: number;
|
|
133
|
+
dailyLoss: number;
|
|
134
|
+
ordersPerMinute: number;
|
|
135
|
+
cancelsPerMinute: number;
|
|
136
|
+
}
|
|
137
|
+
export interface RiskBreach {
|
|
138
|
+
metric: string;
|
|
139
|
+
limit: number;
|
|
140
|
+
current: number;
|
|
141
|
+
level: 'OK' | 'WARNING' | 'CRITICAL';
|
|
142
|
+
action: 'ALERT' | 'AUTO_PAUSE' | 'REJECT_ORDER';
|
|
143
|
+
timestamp: string;
|
|
144
|
+
}
|
|
145
|
+
export interface RiskUpdatePayload {
|
|
146
|
+
event: 'risk_update';
|
|
147
|
+
metrics: {
|
|
148
|
+
limits: RiskLimits;
|
|
149
|
+
utilization: RiskUtilization;
|
|
150
|
+
activeBreaches: RiskBreach[];
|
|
151
|
+
effectiveLimits?: RiskLimits;
|
|
152
|
+
volatility?: {
|
|
153
|
+
atr14: number;
|
|
154
|
+
baselineAtr: number;
|
|
155
|
+
volFactor: number;
|
|
156
|
+
adjusted: boolean;
|
|
157
|
+
};
|
|
158
|
+
drawdownZone?: 'GREEN' | 'YELLOW' | 'ORANGE' | 'RED';
|
|
159
|
+
drawdownZoneMessage?: string;
|
|
160
|
+
regime?: {
|
|
161
|
+
regime: string;
|
|
162
|
+
description: string;
|
|
163
|
+
adjusted: boolean;
|
|
164
|
+
};
|
|
165
|
+
};
|
|
166
|
+
timestamp: string;
|
|
167
|
+
positions?: Array<{
|
|
168
|
+
symbol: string;
|
|
169
|
+
side: 'LONG' | 'SHORT';
|
|
170
|
+
quantity: number;
|
|
171
|
+
entryPrice: number;
|
|
172
|
+
currentPrice: number;
|
|
173
|
+
unrealizedPnl: number;
|
|
174
|
+
unrealizedPnlPercent: number;
|
|
175
|
+
portfolioPercent: number;
|
|
176
|
+
mfeR?: number;
|
|
177
|
+
mfePeakPrice?: number;
|
|
178
|
+
giveBackRatio?: number;
|
|
179
|
+
originalStopPrice?: number;
|
|
180
|
+
liquidationPrice?: number;
|
|
181
|
+
leverage?: number;
|
|
182
|
+
maintenanceMargin?: number;
|
|
183
|
+
marginRatio?: number;
|
|
184
|
+
bracket?: {
|
|
185
|
+
slPrice?: number;
|
|
186
|
+
tpPrice?: number;
|
|
187
|
+
state: string;
|
|
188
|
+
};
|
|
189
|
+
}>;
|
|
190
|
+
balance?: {
|
|
191
|
+
total: number;
|
|
192
|
+
available: number;
|
|
193
|
+
locked: number;
|
|
194
|
+
};
|
|
195
|
+
sessionStartNav?: number;
|
|
196
|
+
/** Realized P&L for TODAY only (filtered by closedAt). Used by the skill's
|
|
197
|
+
* daily-loss breach detection and the agent's daily-performance view. */
|
|
198
|
+
realizedPnlToday?: number;
|
|
199
|
+
/** Cumulative realized P&L across the entire trade history (incl. both open
|
|
200
|
+
* and close fees). Used by the webapp KPI strip. Added Apr 2026 after the
|
|
201
|
+
* original `realizedPnlToday` field was discovered to contain all-time
|
|
202
|
+
* values, misleading the agent about today's performance. */
|
|
203
|
+
realizedPnlAllTime?: number;
|
|
204
|
+
/** Paper session execution costs (since plugin boot), already reflected in
|
|
205
|
+
* equity/NAV — surfaced so the dashboard cost cells don't read $0 (M1).
|
|
206
|
+
* Paper only; omitted in live. */
|
|
207
|
+
sessionFeesPaid?: number;
|
|
208
|
+
sessionAvgSlippageBps?: number;
|
|
209
|
+
/** Mark-to-market account value = wallet + collateral + unrealized P&L.
|
|
210
|
+
* Use this (NOT balance.total) for heat / leverage / exposure math. */
|
|
211
|
+
equity?: number;
|
|
212
|
+
}
|
|
213
|
+
export interface ChatMessage {
|
|
214
|
+
id: string;
|
|
215
|
+
role: 'agent' | 'operator';
|
|
216
|
+
content: string;
|
|
217
|
+
timestamp: string;
|
|
218
|
+
}
|
|
219
|
+
export interface ReconciliationSnapshot {
|
|
220
|
+
positions: Array<{
|
|
221
|
+
symbol: string;
|
|
222
|
+
side: 'LONG' | 'SHORT';
|
|
223
|
+
quantity: number;
|
|
224
|
+
entryPrice: number;
|
|
225
|
+
currentPrice: number;
|
|
226
|
+
unrealizedPnl: number;
|
|
227
|
+
unrealizedPnlPercent: number;
|
|
228
|
+
portfolioPercent: number;
|
|
229
|
+
mfeR?: number;
|
|
230
|
+
mfePeakPrice?: number;
|
|
231
|
+
giveBackRatio?: number;
|
|
232
|
+
originalStopPrice?: number;
|
|
233
|
+
liquidationPrice?: number;
|
|
234
|
+
leverage?: number;
|
|
235
|
+
maintenanceMargin?: number;
|
|
236
|
+
marginRatio?: number;
|
|
237
|
+
bracket?: {
|
|
238
|
+
slPrice?: number;
|
|
239
|
+
tpPrice?: number;
|
|
240
|
+
state: string;
|
|
241
|
+
};
|
|
242
|
+
}>;
|
|
243
|
+
balance: {
|
|
244
|
+
currency: string;
|
|
245
|
+
total: number;
|
|
246
|
+
available: number;
|
|
247
|
+
locked: number;
|
|
248
|
+
};
|
|
249
|
+
openOrders: OrderData[];
|
|
250
|
+
agentState: AgentStateData['state'];
|
|
251
|
+
riskMetrics: RiskUpdatePayload['metrics'];
|
|
252
|
+
gapFill: EventFrame[];
|
|
253
|
+
/** Session start NAV — persisted across skill restarts within the same day. */
|
|
254
|
+
sessionStartNav?: number;
|
|
255
|
+
/** Realized P&L for TODAY only (filtered by closedAt, roundtrip-fee inclusive). */
|
|
256
|
+
realizedPnlToday?: number;
|
|
257
|
+
/** Cumulative realized P&L across all history (roundtrip-fee inclusive). */
|
|
258
|
+
realizedPnlAllTime?: number;
|
|
259
|
+
/** Paper session execution costs (since plugin boot) for the dashboard cost
|
|
260
|
+
* cells (M1). Paper only; omitted in live. */
|
|
261
|
+
sessionFeesPaid?: number;
|
|
262
|
+
sessionAvgSlippageBps?: number;
|
|
263
|
+
/** Mark-to-market account value (wallet + collateral + unrealized P&L). */
|
|
264
|
+
equity?: number;
|
|
265
|
+
/** Current trading mode (Phase 9b) */
|
|
266
|
+
tradingMode?: TradingMode;
|
|
267
|
+
}
|
|
268
|
+
export type TrendDirection = 'bullish' | 'bearish' | 'neutral';
|
|
269
|
+
export type MarketRegime = 'trending' | 'ranging';
|
|
270
|
+
export type MomentumLevel = 'strong' | 'moderate' | 'weak';
|
|
271
|
+
export interface TimeframeAnalysis {
|
|
272
|
+
timeframe: string;
|
|
273
|
+
direction: TrendDirection;
|
|
274
|
+
regime: MarketRegime;
|
|
275
|
+
momentum: MomentumLevel;
|
|
276
|
+
rsiValue: number | null;
|
|
277
|
+
priceVsSma: number | null;
|
|
278
|
+
emaFast: number | null;
|
|
279
|
+
emaSlow: number | null;
|
|
280
|
+
changePercent: number | null;
|
|
281
|
+
candles: number;
|
|
282
|
+
atr14?: number;
|
|
283
|
+
}
|
|
284
|
+
export interface MarketStructureData {
|
|
285
|
+
symbol: string;
|
|
286
|
+
timeframes: TimeframeAnalysis[];
|
|
287
|
+
alignment: {
|
|
288
|
+
bullish: number;
|
|
289
|
+
bearish: number;
|
|
290
|
+
neutral: number;
|
|
291
|
+
total: number;
|
|
292
|
+
summary: string;
|
|
293
|
+
};
|
|
294
|
+
atr?: {
|
|
295
|
+
atr14: number;
|
|
296
|
+
atrPercent: number;
|
|
297
|
+
};
|
|
298
|
+
timestamp: string;
|
|
299
|
+
}
|
|
300
|
+
export interface CryptoMetricsData {
|
|
301
|
+
symbol: string;
|
|
302
|
+
fundingRate: number | null;
|
|
303
|
+
fundingRateAnnualized: number | null;
|
|
304
|
+
nextFundingTime: string | null;
|
|
305
|
+
openInterest: number | null;
|
|
306
|
+
openInterestUsd: number | null;
|
|
307
|
+
timestamp: string;
|
|
308
|
+
}
|
|
309
|
+
export interface VolumeAnalysisData {
|
|
310
|
+
symbol: string;
|
|
311
|
+
timeframe: string;
|
|
312
|
+
volumeExpansion: number;
|
|
313
|
+
closePosition: number;
|
|
314
|
+
directionalThrust: number;
|
|
315
|
+
buyVolEstimate: number;
|
|
316
|
+
avgVolume: number;
|
|
317
|
+
currentVolume: number;
|
|
318
|
+
barsAnalyzed: number;
|
|
319
|
+
timestamp: string;
|
|
320
|
+
}
|
|
321
|
+
export interface RegimeData {
|
|
322
|
+
event: 'regime_update';
|
|
323
|
+
symbol: string;
|
|
324
|
+
regime: 'TREND_UP' | 'TREND_DOWN' | 'RANGE_TIGHT' | 'RANGE_WIDE' | 'VOLATILITY_EXPANSION' | 'AVOID' | 'UNKNOWN';
|
|
325
|
+
confidence: number;
|
|
326
|
+
probabilities: Record<string, number>;
|
|
327
|
+
featuresSnapshot: Record<string, number>;
|
|
328
|
+
durationSeconds: number | null;
|
|
329
|
+
timestamp: string;
|
|
330
|
+
}
|
|
331
|
+
export interface SignalConditionData {
|
|
332
|
+
name: string;
|
|
333
|
+
met: boolean;
|
|
334
|
+
currentValue: number;
|
|
335
|
+
threshold: number;
|
|
336
|
+
description: string;
|
|
337
|
+
}
|
|
338
|
+
export interface StrategyStateData {
|
|
339
|
+
strategy: string;
|
|
340
|
+
direction: 'LONG' | 'SHORT' | null;
|
|
341
|
+
regimeGated: boolean;
|
|
342
|
+
regimeRequired: string[];
|
|
343
|
+
currentRegime: string;
|
|
344
|
+
regimeConfidence: number;
|
|
345
|
+
confluenceScore: number;
|
|
346
|
+
conditions: SignalConditionData[];
|
|
347
|
+
}
|
|
348
|
+
export interface SignalEventData {
|
|
349
|
+
signalId: string;
|
|
350
|
+
timestamp: string;
|
|
351
|
+
symbol: string;
|
|
352
|
+
strategy: string;
|
|
353
|
+
direction: 'LONG' | 'SHORT';
|
|
354
|
+
regime: string;
|
|
355
|
+
regimeConfidence: number;
|
|
356
|
+
confluenceScore: number;
|
|
357
|
+
conditions: SignalConditionData[];
|
|
358
|
+
entryZone: {
|
|
359
|
+
low: number;
|
|
360
|
+
high: number;
|
|
361
|
+
};
|
|
362
|
+
stopLevel: number;
|
|
363
|
+
targets: number[];
|
|
364
|
+
}
|
|
365
|
+
export interface SignalData {
|
|
366
|
+
event: 'signal_update';
|
|
367
|
+
activeStrategies: StrategyStateData[];
|
|
368
|
+
recentSignals: SignalEventData[];
|
|
369
|
+
timestamp: string;
|
|
370
|
+
}
|
|
371
|
+
export type MissionStatusType = 'PENDING' | 'ACCEPTED' | 'EXECUTING' | 'FILLED' | 'EXPIRED' | 'REJECTED';
|
|
372
|
+
export interface SizingDetailsData {
|
|
373
|
+
sizePct: number;
|
|
374
|
+
kellyFraction: number;
|
|
375
|
+
winRate: number;
|
|
376
|
+
avgWinLossRatio: number;
|
|
377
|
+
tradeCount: number;
|
|
378
|
+
volAdjustment: number;
|
|
379
|
+
cappedReason?: string;
|
|
380
|
+
}
|
|
381
|
+
export interface TradeMissionData {
|
|
382
|
+
missionId: string;
|
|
383
|
+
signalId: string;
|
|
384
|
+
symbol: string;
|
|
385
|
+
direction: 'LONG' | 'SHORT';
|
|
386
|
+
strategy: string;
|
|
387
|
+
regime: string;
|
|
388
|
+
regimeConfidence: number;
|
|
389
|
+
confluenceScore: number;
|
|
390
|
+
conditions: SignalConditionData[];
|
|
391
|
+
entryZone: {
|
|
392
|
+
low: number;
|
|
393
|
+
high: number;
|
|
394
|
+
};
|
|
395
|
+
stopLevel: number;
|
|
396
|
+
targets: Array<{
|
|
397
|
+
price: number;
|
|
398
|
+
pct: number;
|
|
399
|
+
}>;
|
|
400
|
+
sizePct: number;
|
|
401
|
+
sizingDetails: SizingDetailsData;
|
|
402
|
+
status: MissionStatusType;
|
|
403
|
+
statusDetails?: Record<string, unknown>;
|
|
404
|
+
expiresAt: string;
|
|
405
|
+
createdAt: string;
|
|
406
|
+
updatedAt: string;
|
|
407
|
+
}
|
|
408
|
+
export interface MissionData {
|
|
409
|
+
event: 'mission_update';
|
|
410
|
+
activeMissions: TradeMissionData[];
|
|
411
|
+
recentCompleted: TradeMissionData[];
|
|
412
|
+
timestamp: string;
|
|
413
|
+
}
|
|
414
|
+
export interface StrategyMetricsData {
|
|
415
|
+
strategy: string;
|
|
416
|
+
winRate20: number;
|
|
417
|
+
winRate50: number;
|
|
418
|
+
winRateAll: number;
|
|
419
|
+
expectancy20: number;
|
|
420
|
+
expectancyAll: number;
|
|
421
|
+
profitFactor: number;
|
|
422
|
+
avgHoldWinners: number;
|
|
423
|
+
avgHoldLosers: number;
|
|
424
|
+
totalTrades: number;
|
|
425
|
+
bestTradePct: number;
|
|
426
|
+
worstTradePct: number;
|
|
427
|
+
avgPnlPct: number;
|
|
428
|
+
sharpe: number;
|
|
429
|
+
gated: boolean;
|
|
430
|
+
gatedReason?: string;
|
|
431
|
+
gatedAt?: string;
|
|
432
|
+
}
|
|
433
|
+
export interface RegimePerformanceData {
|
|
434
|
+
regime: string;
|
|
435
|
+
trades: number;
|
|
436
|
+
winRate: number;
|
|
437
|
+
expectancy: number;
|
|
438
|
+
avgPnlPct: number;
|
|
439
|
+
}
|
|
440
|
+
export interface EquityPointData {
|
|
441
|
+
timestamp: string;
|
|
442
|
+
cumulativePnl: number;
|
|
443
|
+
drawdownPct: number;
|
|
444
|
+
}
|
|
445
|
+
export interface DegradationAlertData {
|
|
446
|
+
strategy: string;
|
|
447
|
+
type: 'GATED' | 'UNGATED';
|
|
448
|
+
reason: string;
|
|
449
|
+
expectancy20: number;
|
|
450
|
+
timestamp: string;
|
|
451
|
+
}
|
|
452
|
+
export interface AnalyticsData {
|
|
453
|
+
event: 'analytics_update';
|
|
454
|
+
strategies: StrategyMetricsData[];
|
|
455
|
+
regimeBreakdown: RegimePerformanceData[];
|
|
456
|
+
equityCurve: EquityPointData[];
|
|
457
|
+
degradationAlerts: DegradationAlertData[];
|
|
458
|
+
summary: {
|
|
459
|
+
totalTrades: number;
|
|
460
|
+
overallWinRate: number;
|
|
461
|
+
overallExpectancy: number;
|
|
462
|
+
overallSharpe: number;
|
|
463
|
+
activeStrategies: number;
|
|
464
|
+
gatedStrategies: number;
|
|
465
|
+
peakDrawdownPct: number;
|
|
466
|
+
};
|
|
467
|
+
timestamp: string;
|
|
468
|
+
}
|
|
469
|
+
export interface DecisionTraceNearMiss {
|
|
470
|
+
strategy: string;
|
|
471
|
+
direction: 'LONG' | 'SHORT' | null;
|
|
472
|
+
confluenceScore: number;
|
|
473
|
+
totalConditions: number;
|
|
474
|
+
missingConditions: SignalConditionData[];
|
|
475
|
+
distanceToSignal: number;
|
|
476
|
+
}
|
|
477
|
+
export interface DecisionTraceFactor {
|
|
478
|
+
name: string;
|
|
479
|
+
value: string;
|
|
480
|
+
impact: 'bullish' | 'bearish' | 'neutral';
|
|
481
|
+
weight: number;
|
|
482
|
+
}
|
|
483
|
+
export interface DecisionTraceData {
|
|
484
|
+
event: 'decision_trace';
|
|
485
|
+
symbol: string;
|
|
486
|
+
regime: {
|
|
487
|
+
current: string;
|
|
488
|
+
confidence: number;
|
|
489
|
+
probabilities: Record<string, number>;
|
|
490
|
+
};
|
|
491
|
+
bias: 'LONG' | 'SHORT' | 'NEUTRAL';
|
|
492
|
+
biasStrength: number;
|
|
493
|
+
factors: DecisionTraceFactor[];
|
|
494
|
+
activeStrategies: Array<{
|
|
495
|
+
strategy: string;
|
|
496
|
+
direction: 'LONG' | 'SHORT' | null;
|
|
497
|
+
confluenceScore: number;
|
|
498
|
+
totalConditions: number;
|
|
499
|
+
regimeGated: boolean;
|
|
500
|
+
ready: boolean;
|
|
501
|
+
}>;
|
|
502
|
+
nearMisses: DecisionTraceNearMiss[];
|
|
503
|
+
recentSignalCount: number;
|
|
504
|
+
timestamp: string;
|
|
505
|
+
}
|
|
506
|
+
import type { TradingMode as _TradingMode } from '@reefclaw/shared';
|
|
507
|
+
import { isTradingMode as _isTradingMode } from '@reefclaw/shared';
|
|
508
|
+
export type TradingMode = _TradingMode;
|
|
509
|
+
export declare const isTradingMode: typeof _isTradingMode;
|
|
510
|
+
/** Shadow comparison event — paper fill vs live estimate. */
|
|
511
|
+
export interface ShadowComparisonData {
|
|
512
|
+
event: 'shadow_comparison';
|
|
513
|
+
orderId: string;
|
|
514
|
+
symbol: string;
|
|
515
|
+
side: 'BUY' | 'SELL';
|
|
516
|
+
type: 'MARKET' | 'LIMIT';
|
|
517
|
+
amount: number;
|
|
518
|
+
paperFillPrice: number;
|
|
519
|
+
shadowEstimatePrice: number;
|
|
520
|
+
deltaBps: number;
|
|
521
|
+
paperFee: number;
|
|
522
|
+
shadowEstimateFee: number;
|
|
523
|
+
bookDepthUsed: number;
|
|
524
|
+
bookDepthAvailable: boolean;
|
|
525
|
+
timestamp: string;
|
|
526
|
+
}
|
|
527
|
+
/** Trading mode update event. */
|
|
528
|
+
export interface TradingModeData {
|
|
529
|
+
event: 'trading_mode';
|
|
530
|
+
mode: TradingMode;
|
|
531
|
+
shadowMetrics?: {
|
|
532
|
+
totalShadowTrades: number;
|
|
533
|
+
avgDeltaBps: number;
|
|
534
|
+
worstDeltaBps: number;
|
|
535
|
+
tradingDays: number;
|
|
536
|
+
readyForUpgrade: boolean;
|
|
537
|
+
upgradeBlockers: string[];
|
|
538
|
+
};
|
|
539
|
+
timestamp: string;
|
|
540
|
+
}
|
|
541
|
+
export interface TradeJournalEntry {
|
|
542
|
+
id: string;
|
|
543
|
+
symbol: string;
|
|
544
|
+
side: 'BUY' | 'SELL';
|
|
545
|
+
action: 'OPEN' | 'CLOSE' | 'ADD' | 'REDUCE';
|
|
546
|
+
quantity: number;
|
|
547
|
+
price: number;
|
|
548
|
+
/** Market structure snapshot at trade time */
|
|
549
|
+
marketContext: {
|
|
550
|
+
direction5m: string | null;
|
|
551
|
+
direction1h: string | null;
|
|
552
|
+
direction4h: string | null;
|
|
553
|
+
alignment: string | null;
|
|
554
|
+
fundingRate: number | null;
|
|
555
|
+
volumeExpansion: number | null;
|
|
556
|
+
closePosition: number | null;
|
|
557
|
+
};
|
|
558
|
+
/** Risk snapshot at trade time */
|
|
559
|
+
riskContext: {
|
|
560
|
+
grossExposure: number;
|
|
561
|
+
netExposure: number;
|
|
562
|
+
dailyDrawdown: number;
|
|
563
|
+
heatScore: number;
|
|
564
|
+
};
|
|
565
|
+
timestamp: string;
|
|
566
|
+
}
|
|
567
|
+
export interface ConnectorConfig {
|
|
568
|
+
relayUrl: string;
|
|
569
|
+
userId: string;
|
|
570
|
+
token: string;
|
|
571
|
+
reconnect?: {
|
|
572
|
+
baseDelayMs?: number;
|
|
573
|
+
maxDelayMs?: number;
|
|
574
|
+
maxFastAttempts?: number;
|
|
575
|
+
jitterFactor?: number;
|
|
576
|
+
slowRetryMs?: number;
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
/** Close codes that indicate fatal auth errors — do not reconnect.
|
|
580
|
+
* 4001 = invalid/mismatched token (permanent failure).
|
|
581
|
+
* 4002 removed — relay now evicts stale connections instead of rejecting new ones,
|
|
582
|
+
* but even if an old relay is deployed, the connector should retry (old connection
|
|
583
|
+
* will time out and the next attempt will succeed). */
|
|
584
|
+
export declare const FATAL_CLOSE_CODES: readonly [4001];
|
package/bridge/types.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Protocol types — re-exported from @reefclaw/shared (canonical source of truth).
|
|
2
|
+
export { VALID_CHANNELS, VALID_EMERGENCY_ACTIONS } from '@reefclaw/shared';
|
|
3
|
+
// ---- Command whitelist ----
|
|
4
|
+
/** Methods the skill accepts from the relay (browser → skill) */
|
|
5
|
+
export const ALLOWED_METHODS = [
|
|
6
|
+
'emergency.kill',
|
|
7
|
+
'emergency.flatten',
|
|
8
|
+
'emergency.pause',
|
|
9
|
+
'emergency.resume',
|
|
10
|
+
'reconcile',
|
|
11
|
+
'chat.send',
|
|
12
|
+
'skill.update',
|
|
13
|
+
'close_position',
|
|
14
|
+
// Operator-only onboarding methods (PR2+PR4). Gated by OPERATOR_WRITE_METHODS —
|
|
15
|
+
// the bridge refuses to handle these unless the call goes through the
|
|
16
|
+
// operator.write scope enforcement path. See bridge.ts.
|
|
17
|
+
'set_trading_mode',
|
|
18
|
+
'set_exchange_credentials',
|
|
19
|
+
'test_exchange_credentials',
|
|
20
|
+
'clear_exchange_credentials',
|
|
21
|
+
// Bracket-orders config (Phase 3.5b) — operator.write-gated.
|
|
22
|
+
'get_bracket_config',
|
|
23
|
+
'set_bracket_requirement',
|
|
24
|
+
];
|
|
25
|
+
/** Subset of ALLOWED_METHODS that require operator.write scope. The bridge
|
|
26
|
+
* enforces this before dispatching — a session without the scope gets a
|
|
27
|
+
* 403 error. PR2 ships the scope as session-wide (inherited from the Clerk
|
|
28
|
+
* authenticated browser session) because the skill trusts the relay to
|
|
29
|
+
* scope rooms per user; per-method operator gating is defense-in-depth and
|
|
30
|
+
* a hook for PR4 fine-grained roles. */
|
|
31
|
+
export const OPERATOR_WRITE_METHODS = new Set([
|
|
32
|
+
'set_trading_mode',
|
|
33
|
+
'set_exchange_credentials',
|
|
34
|
+
'test_exchange_credentials',
|
|
35
|
+
'clear_exchange_credentials',
|
|
36
|
+
'get_bracket_config',
|
|
37
|
+
'set_bracket_requirement',
|
|
38
|
+
'emergency.kill',
|
|
39
|
+
'emergency.flatten',
|
|
40
|
+
'emergency.pause',
|
|
41
|
+
'emergency.resume',
|
|
42
|
+
]);
|
|
43
|
+
import { isTradingMode as _isTradingMode } from '@reefclaw/shared';
|
|
44
|
+
export const isTradingMode = _isTradingMode;
|
|
45
|
+
/** Close codes that indicate fatal auth errors — do not reconnect.
|
|
46
|
+
* 4001 = invalid/mismatched token (permanent failure).
|
|
47
|
+
* 4002 removed — relay now evicts stale connections instead of rejecting new ones,
|
|
48
|
+
* but even if an old relay is deployed, the connector should retry (old connection
|
|
49
|
+
* will time out and the next attempt will succeed). */
|
|
50
|
+
export const FATAL_CLOSE_CODES = [4001];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Shared reconnection utilities (exponential backoff with jitter)
|
|
2
|
+
export function computeDelay(attempt, config) {
|
|
3
|
+
const base = Math.min(config.baseDelayMs * Math.pow(2, attempt), config.maxDelayMs);
|
|
4
|
+
const jitter = base * config.jitterFactor;
|
|
5
|
+
return base - jitter + Math.random() * jitter * 2;
|
|
6
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pinned Ed25519 PUBLIC keys (base64 of the raw 32-byte key) trusted to sign OTA
|
|
3
|
+
* SKILL.md updates. Multiple entries enable key rotation (accept current + next,
|
|
4
|
+
* retire the old after every client has updated). EMPTY until the operator pins
|
|
5
|
+
* one — see the header for provisioning.
|
|
6
|
+
*/
|
|
7
|
+
export declare const TRUSTED_SKILL_SIGNING_KEYS: string[];
|
|
8
|
+
export interface SignedSkillEnvelope {
|
|
9
|
+
version: string;
|
|
10
|
+
content: string;
|
|
11
|
+
contentSha256?: string;
|
|
12
|
+
signedAt?: string;
|
|
13
|
+
/** base64 Ed25519 signature over signedMessage(version, contentSha256, signedAt) */
|
|
14
|
+
signature?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface VerifyResult {
|
|
17
|
+
ok: boolean;
|
|
18
|
+
reason?: string;
|
|
19
|
+
}
|
|
20
|
+
/** Lowercase hex SHA-256 of the UTF-8 content. MUST match the Python signer. */
|
|
21
|
+
export declare function sha256Hex(content: string): string;
|
|
22
|
+
/** Canonical signed message — MUST match deploy-skillmd-ota.py byte-for-byte. */
|
|
23
|
+
export declare function signedMessage(version: string, contentSha256: string, signedAt: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Is OTA signature verification enforced?
|
|
26
|
+
*
|
|
27
|
+
* Default **OFF** while C1 (signed OTA) is ON HOLD — see
|
|
28
|
+
* docs/PRE_LAUNCH_SECURITY_HARDENING.md §2.5. Keeping it off by default makes
|
|
29
|
+
* this whole module DORMANT, so deploying skill/relay for UNRELATED reasons can
|
|
30
|
+
* never break the existing (unsigned) OTA flow — no env flag to remember.
|
|
31
|
+
*
|
|
32
|
+
* To ENABLE signed-OTA (when the agent-update mechanism is finalized): pin a
|
|
33
|
+
* public key in TRUSTED_SKILL_SIGNING_KEYS **and** set
|
|
34
|
+
* SKILL_OTA_REQUIRE_SIGNATURE=on. Both are required — a pinned key alone does
|
|
35
|
+
* nothing without the flag, and the flag alone fails closed (no key → reject).
|
|
36
|
+
*/
|
|
37
|
+
export declare function signatureRequired(): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Verify a signed OTA envelope against the pinned (or supplied) trusted keys.
|
|
40
|
+
* Checks: required fields present, content hash matches (no tampering), the
|
|
41
|
+
* frontmatter version matches the signed version (no number-bump replay), and
|
|
42
|
+
* the Ed25519 signature verifies under some trusted key. Pure — does NOT touch
|
|
43
|
+
* disk or the replay clock; the caller enforces monotonic signedAt.
|
|
44
|
+
*/
|
|
45
|
+
export declare function verifySkillSignature(env: SignedSkillEnvelope, opts?: {
|
|
46
|
+
trustedKeys?: string[];
|
|
47
|
+
}): VerifyResult;
|
|
48
|
+
/** Last applied signedAt as epoch ms, 0 if none/unreadable (replay clock). */
|
|
49
|
+
export declare function readLastAppliedSignedAtMs(): number;
|
|
50
|
+
/** Persist the signedAt of the just-applied update (monotonic replay clock). */
|
|
51
|
+
export declare function recordAppliedSignedAt(signedAt: string): void;
|