@raintree-technology/perps 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 (316) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/LICENSE +21 -0
  3. package/README.md +175 -0
  4. package/dist/adapters/aevo.d.ts +64 -0
  5. package/dist/adapters/aevo.js +899 -0
  6. package/dist/adapters/certification.d.ts +33 -0
  7. package/dist/adapters/certification.js +99 -0
  8. package/dist/adapters/decibel/order-manager.d.ts +45 -0
  9. package/dist/adapters/decibel/order-manager.js +140 -0
  10. package/dist/adapters/decibel/rest-client.d.ts +176 -0
  11. package/dist/adapters/decibel/rest-client.js +155 -0
  12. package/dist/adapters/decibel/ws-feed.d.ts +28 -0
  13. package/dist/adapters/decibel/ws-feed.js +166 -0
  14. package/dist/adapters/decibel.d.ts +108 -0
  15. package/dist/adapters/decibel.js +1377 -0
  16. package/dist/adapters/hyperliquid.d.ts +63 -0
  17. package/dist/adapters/hyperliquid.js +797 -0
  18. package/dist/adapters/index.d.ts +11 -0
  19. package/dist/adapters/index.js +12 -0
  20. package/dist/adapters/interface.d.ts +310 -0
  21. package/dist/adapters/interface.js +15 -0
  22. package/dist/adapters/orderly.d.ts +70 -0
  23. package/dist/adapters/orderly.js +936 -0
  24. package/dist/adapters/paradex.d.ts +69 -0
  25. package/dist/adapters/paradex.js +862 -0
  26. package/dist/adapters/utils.d.ts +17 -0
  27. package/dist/adapters/utils.js +122 -0
  28. package/dist/cli/command-metadata.d.ts +2 -0
  29. package/dist/cli/command-metadata.js +44 -0
  30. package/dist/cli/context.d.ts +14 -0
  31. package/dist/cli/context.js +59 -0
  32. package/dist/cli/experience.d.ts +48 -0
  33. package/dist/cli/experience.js +243 -0
  34. package/dist/cli/ink/app/AppShell.d.ts +12 -0
  35. package/dist/cli/ink/app/AppShell.js +32 -0
  36. package/dist/cli/ink/app/MetricStrip.d.ts +6 -0
  37. package/dist/cli/ink/app/MetricStrip.js +14 -0
  38. package/dist/cli/ink/app/Panel.d.ts +9 -0
  39. package/dist/cli/ink/app/Panel.js +7 -0
  40. package/dist/cli/ink/app/ascii.d.ts +2 -0
  41. package/dist/cli/ink/app/ascii.js +46 -0
  42. package/dist/cli/ink/app/index.d.ts +5 -0
  43. package/dist/cli/ink/app/index.js +4 -0
  44. package/dist/cli/ink/app/types.d.ts +15 -0
  45. package/dist/cli/ink/app/types.js +1 -0
  46. package/dist/cli/ink/components/PnL.d.ts +12 -0
  47. package/dist/cli/ink/components/PnL.js +23 -0
  48. package/dist/cli/ink/components/Spinner.d.ts +13 -0
  49. package/dist/cli/ink/components/Spinner.js +13 -0
  50. package/dist/cli/ink/components/Table.d.ts +14 -0
  51. package/dist/cli/ink/components/Table.js +42 -0
  52. package/dist/cli/ink/components/WatchHeader.d.ts +10 -0
  53. package/dist/cli/ink/components/WatchHeader.js +18 -0
  54. package/dist/cli/ink/components/index.d.ts +4 -0
  55. package/dist/cli/ink/components/index.js +4 -0
  56. package/dist/cli/ink/index.d.ts +4 -0
  57. package/dist/cli/ink/index.js +4 -0
  58. package/dist/cli/ink/render.d.ts +12 -0
  59. package/dist/cli/ink/render.js +21 -0
  60. package/dist/cli/ink/theme.d.ts +29 -0
  61. package/dist/cli/ink/theme.js +40 -0
  62. package/dist/cli/network-defaults.d.ts +10 -0
  63. package/dist/cli/network-defaults.js +35 -0
  64. package/dist/cli/output.d.ts +11 -0
  65. package/dist/cli/output.js +115 -0
  66. package/dist/cli/program.d.ts +18 -0
  67. package/dist/cli/program.js +164 -0
  68. package/dist/cli/watch.d.ts +19 -0
  69. package/dist/cli/watch.js +35 -0
  70. package/dist/client/index.d.ts +55 -0
  71. package/dist/client/index.js +157 -0
  72. package/dist/commands/account/add.d.ts +2 -0
  73. package/dist/commands/account/add.js +510 -0
  74. package/dist/commands/account/balances-simple.d.ts +5 -0
  75. package/dist/commands/account/balances-simple.js +63 -0
  76. package/dist/commands/account/index.d.ts +2 -0
  77. package/dist/commands/account/index.js +17 -0
  78. package/dist/commands/account/ls.d.ts +2 -0
  79. package/dist/commands/account/ls.js +95 -0
  80. package/dist/commands/account/positions-simple.d.ts +5 -0
  81. package/dist/commands/account/positions-simple.js +77 -0
  82. package/dist/commands/account/remove.d.ts +2 -0
  83. package/dist/commands/account/remove.js +47 -0
  84. package/dist/commands/account/set-default.d.ts +2 -0
  85. package/dist/commands/account/set-default.js +47 -0
  86. package/dist/commands/agent/index.d.ts +2 -0
  87. package/dist/commands/agent/index.js +126 -0
  88. package/dist/commands/arb/alert.d.ts +6 -0
  89. package/dist/commands/arb/alert.js +88 -0
  90. package/dist/commands/arb/basis-execute.d.ts +6 -0
  91. package/dist/commands/arb/basis-execute.js +332 -0
  92. package/dist/commands/arb/basis.d.ts +6 -0
  93. package/dist/commands/arb/basis.js +181 -0
  94. package/dist/commands/arb/compare.d.ts +6 -0
  95. package/dist/commands/arb/compare.js +216 -0
  96. package/dist/commands/arb/execute.d.ts +6 -0
  97. package/dist/commands/arb/execute.js +467 -0
  98. package/dist/commands/arb/funding.d.ts +6 -0
  99. package/dist/commands/arb/funding.js +201 -0
  100. package/dist/commands/arb/history.d.ts +6 -0
  101. package/dist/commands/arb/history.js +153 -0
  102. package/dist/commands/arb/index.d.ts +6 -0
  103. package/dist/commands/arb/index.js +29 -0
  104. package/dist/commands/arb/positions.d.ts +6 -0
  105. package/dist/commands/arb/positions.js +158 -0
  106. package/dist/commands/arb/spread.d.ts +6 -0
  107. package/dist/commands/arb/spread.js +253 -0
  108. package/dist/commands/arb/track.d.ts +6 -0
  109. package/dist/commands/arb/track.js +259 -0
  110. package/dist/commands/asset/book-simple.d.ts +5 -0
  111. package/dist/commands/asset/book-simple.js +77 -0
  112. package/dist/commands/asset/index.d.ts +2 -0
  113. package/dist/commands/asset/index.js +5 -0
  114. package/dist/commands/completion.d.ts +2 -0
  115. package/dist/commands/completion.js +161 -0
  116. package/dist/commands/config/index.d.ts +5 -0
  117. package/dist/commands/config/index.js +109 -0
  118. package/dist/commands/data/index.d.ts +31 -0
  119. package/dist/commands/data/index.js +1466 -0
  120. package/dist/commands/doctor.d.ts +2 -0
  121. package/dist/commands/doctor.js +201 -0
  122. package/dist/commands/exchange/index.d.ts +2 -0
  123. package/dist/commands/exchange/index.js +107 -0
  124. package/dist/commands/index.d.ts +2 -0
  125. package/dist/commands/index.js +48 -0
  126. package/dist/commands/markets/index.d.ts +2 -0
  127. package/dist/commands/markets/index.js +5 -0
  128. package/dist/commands/markets/ls-simple.d.ts +7 -0
  129. package/dist/commands/markets/ls-simple.js +277 -0
  130. package/dist/commands/operator/index.d.ts +2 -0
  131. package/dist/commands/operator/index.js +146 -0
  132. package/dist/commands/order/cancel-simple.d.ts +5 -0
  133. package/dist/commands/order/cancel-simple.js +104 -0
  134. package/dist/commands/order/index.d.ts +2 -0
  135. package/dist/commands/order/index.js +13 -0
  136. package/dist/commands/order/limit-simple.d.ts +5 -0
  137. package/dist/commands/order/limit-simple.js +195 -0
  138. package/dist/commands/order/market-simple.d.ts +5 -0
  139. package/dist/commands/order/market-simple.js +190 -0
  140. package/dist/commands/order/shared.d.ts +17 -0
  141. package/dist/commands/order/shared.js +51 -0
  142. package/dist/commands/order/trigger-simple.d.ts +5 -0
  143. package/dist/commands/order/trigger-simple.js +246 -0
  144. package/dist/commands/referral/index.d.ts +2 -0
  145. package/dist/commands/referral/index.js +7 -0
  146. package/dist/commands/referral/set.d.ts +2 -0
  147. package/dist/commands/referral/set.js +26 -0
  148. package/dist/commands/referral/status.d.ts +2 -0
  149. package/dist/commands/referral/status.js +31 -0
  150. package/dist/commands/replay/index.d.ts +2 -0
  151. package/dist/commands/replay/index.js +152 -0
  152. package/dist/commands/risk/analytics.d.ts +2 -0
  153. package/dist/commands/risk/analytics.js +64 -0
  154. package/dist/commands/risk/audit.d.ts +2 -0
  155. package/dist/commands/risk/audit.js +52 -0
  156. package/dist/commands/risk/index.d.ts +2 -0
  157. package/dist/commands/risk/index.js +9 -0
  158. package/dist/commands/risk/rules.d.ts +2 -0
  159. package/dist/commands/risk/rules.js +102 -0
  160. package/dist/commands/server.d.ts +2 -0
  161. package/dist/commands/server.js +208 -0
  162. package/dist/commands/setup/index.d.ts +2 -0
  163. package/dist/commands/setup/index.js +478 -0
  164. package/dist/commands/signal/index.d.ts +2 -0
  165. package/dist/commands/signal/index.js +129 -0
  166. package/dist/commands/state/index.d.ts +2 -0
  167. package/dist/commands/state/index.js +5 -0
  168. package/dist/commands/state/show.d.ts +2 -0
  169. package/dist/commands/state/show.js +105 -0
  170. package/dist/commands/strategy/index.d.ts +4 -0
  171. package/dist/commands/strategy/index.js +73 -0
  172. package/dist/commands/traces/index.d.ts +2 -0
  173. package/dist/commands/traces/index.js +76 -0
  174. package/dist/commands/ui/demo.d.ts +9 -0
  175. package/dist/commands/ui/demo.js +195 -0
  176. package/dist/commands/ui/index.d.ts +2 -0
  177. package/dist/commands/ui/index.js +7 -0
  178. package/dist/commands/ui/terminal.d.ts +2 -0
  179. package/dist/commands/ui/terminal.js +255 -0
  180. package/dist/commands/upgrade.d.ts +2 -0
  181. package/dist/commands/upgrade.js +98 -0
  182. package/dist/index.d.ts +2 -0
  183. package/dist/index.js +4 -0
  184. package/dist/lib/agent/audit.d.ts +12 -0
  185. package/dist/lib/agent/audit.js +13 -0
  186. package/dist/lib/agent/gateway.d.ts +13 -0
  187. package/dist/lib/agent/gateway.js +598 -0
  188. package/dist/lib/agent/metrics.d.ts +33 -0
  189. package/dist/lib/agent/metrics.js +175 -0
  190. package/dist/lib/agent/signature.d.ts +8 -0
  191. package/dist/lib/agent/signature.js +28 -0
  192. package/dist/lib/agent/tools.d.ts +28 -0
  193. package/dist/lib/agent/tools.js +453 -0
  194. package/dist/lib/agent/x402.d.ts +23 -0
  195. package/dist/lib/agent/x402.js +62 -0
  196. package/dist/lib/api-wallet.d.ts +69 -0
  197. package/dist/lib/api-wallet.js +101 -0
  198. package/dist/lib/balance-watcher.d.ts +25 -0
  199. package/dist/lib/balance-watcher.js +83 -0
  200. package/dist/lib/book-watcher.d.ts +25 -0
  201. package/dist/lib/book-watcher.js +48 -0
  202. package/dist/lib/config.d.ts +88 -0
  203. package/dist/lib/config.js +427 -0
  204. package/dist/lib/constants.d.ts +50 -0
  205. package/dist/lib/constants.js +84 -0
  206. package/dist/lib/contracts.d.ts +7 -0
  207. package/dist/lib/contracts.js +8 -0
  208. package/dist/lib/credential-vault.d.ts +22 -0
  209. package/dist/lib/credential-vault.js +109 -0
  210. package/dist/lib/db/accounts.d.ts +83 -0
  211. package/dist/lib/db/accounts.js +203 -0
  212. package/dist/lib/db/funding-history.d.ts +69 -0
  213. package/dist/lib/db/funding-history.js +183 -0
  214. package/dist/lib/db/index.d.ts +11 -0
  215. package/dist/lib/db/index.js +272 -0
  216. package/dist/lib/events/bus.d.ts +10 -0
  217. package/dist/lib/events/bus.js +17 -0
  218. package/dist/lib/events/types.d.ts +51 -0
  219. package/dist/lib/events/types.js +1 -0
  220. package/dist/lib/exchange.d.ts +30 -0
  221. package/dist/lib/exchange.js +84 -0
  222. package/dist/lib/execution/journal.d.ts +25 -0
  223. package/dist/lib/execution/journal.js +158 -0
  224. package/dist/lib/execution/safety.d.ts +34 -0
  225. package/dist/lib/execution/safety.js +197 -0
  226. package/dist/lib/exit-codes.d.ts +18 -0
  227. package/dist/lib/exit-codes.js +60 -0
  228. package/dist/lib/fetch.d.ts +18 -0
  229. package/dist/lib/fetch.js +66 -0
  230. package/dist/lib/fs-security.d.ts +10 -0
  231. package/dist/lib/fs-security.js +26 -0
  232. package/dist/lib/funding-tracker.d.ts +40 -0
  233. package/dist/lib/funding-tracker.js +118 -0
  234. package/dist/lib/logger.d.ts +27 -0
  235. package/dist/lib/logger.js +82 -0
  236. package/dist/lib/network-model.d.ts +13 -0
  237. package/dist/lib/network-model.js +30 -0
  238. package/dist/lib/onboarding.d.ts +133 -0
  239. package/dist/lib/onboarding.js +1459 -0
  240. package/dist/lib/operator-state.d.ts +25 -0
  241. package/dist/lib/operator-state.js +82 -0
  242. package/dist/lib/orders-watcher.d.ts +24 -0
  243. package/dist/lib/orders-watcher.js +74 -0
  244. package/dist/lib/paths.d.ts +20 -0
  245. package/dist/lib/paths.js +23 -0
  246. package/dist/lib/portfolio-watcher.d.ts +33 -0
  247. package/dist/lib/portfolio-watcher.js +95 -0
  248. package/dist/lib/position-watcher.d.ts +16 -0
  249. package/dist/lib/position-watcher.js +44 -0
  250. package/dist/lib/price-watcher.d.ts +15 -0
  251. package/dist/lib/price-watcher.js +84 -0
  252. package/dist/lib/prompts.d.ts +32 -0
  253. package/dist/lib/prompts.js +105 -0
  254. package/dist/lib/rate-limit.d.ts +32 -0
  255. package/dist/lib/rate-limit.js +88 -0
  256. package/dist/lib/risk/analytics.d.ts +39 -0
  257. package/dist/lib/risk/analytics.js +98 -0
  258. package/dist/lib/risk/drawdown.d.ts +18 -0
  259. package/dist/lib/risk/drawdown.js +49 -0
  260. package/dist/lib/risk/evaluation-log.d.ts +29 -0
  261. package/dist/lib/risk/evaluation-log.js +61 -0
  262. package/dist/lib/risk/index.d.ts +4 -0
  263. package/dist/lib/risk/index.js +4 -0
  264. package/dist/lib/risk/limits.d.ts +23 -0
  265. package/dist/lib/risk/limits.js +27 -0
  266. package/dist/lib/risk/manager.d.ts +32 -0
  267. package/dist/lib/risk/manager.js +85 -0
  268. package/dist/lib/risk/policy-middleware.d.ts +33 -0
  269. package/dist/lib/risk/policy-middleware.js +267 -0
  270. package/dist/lib/risk/position-sizer.d.ts +9 -0
  271. package/dist/lib/risk/position-sizer.js +14 -0
  272. package/dist/lib/risk/rules-store.d.ts +16 -0
  273. package/dist/lib/risk/rules-store.js +47 -0
  274. package/dist/lib/schema.d.ts +254 -0
  275. package/dist/lib/schema.js +199 -0
  276. package/dist/lib/secrets.d.ts +3 -0
  277. package/dist/lib/secrets.js +62 -0
  278. package/dist/lib/settings.d.ts +24 -0
  279. package/dist/lib/settings.js +86 -0
  280. package/dist/lib/signals.d.ts +73 -0
  281. package/dist/lib/signals.js +136 -0
  282. package/dist/lib/stable-stringify.d.ts +6 -0
  283. package/dist/lib/stable-stringify.js +17 -0
  284. package/dist/lib/state-context.d.ts +44 -0
  285. package/dist/lib/state-context.js +133 -0
  286. package/dist/lib/strategy/basis-trade.d.ts +2 -0
  287. package/dist/lib/strategy/basis-trade.js +24 -0
  288. package/dist/lib/strategy/funding-arb.d.ts +2 -0
  289. package/dist/lib/strategy/funding-arb.js +23 -0
  290. package/dist/lib/strategy/interface.d.ts +23 -0
  291. package/dist/lib/strategy/interface.js +1 -0
  292. package/dist/lib/strategy/registry.d.ts +4 -0
  293. package/dist/lib/strategy/registry.js +10 -0
  294. package/dist/lib/telemetry.d.ts +25 -0
  295. package/dist/lib/telemetry.js +101 -0
  296. package/dist/lib/trace-queries.d.ts +20 -0
  297. package/dist/lib/trace-queries.js +133 -0
  298. package/dist/lib/trace.d.ts +1 -0
  299. package/dist/lib/trace.js +4 -0
  300. package/dist/lib/trade-reputation.d.ts +6 -0
  301. package/dist/lib/trade-reputation.js +99 -0
  302. package/dist/lib/ui-tokens.d.ts +21 -0
  303. package/dist/lib/ui-tokens.js +26 -0
  304. package/dist/lib/validate.d.ts +39 -0
  305. package/dist/lib/validate.js +108 -0
  306. package/dist/lib/validation.d.ts +9 -0
  307. package/dist/lib/validation.js +64 -0
  308. package/dist/server/cache.d.ts +38 -0
  309. package/dist/server/cache.js +56 -0
  310. package/dist/server/index.d.ts +2 -0
  311. package/dist/server/index.js +89 -0
  312. package/dist/server/ipc.d.ts +18 -0
  313. package/dist/server/ipc.js +159 -0
  314. package/dist/server/subscriptions.d.ts +18 -0
  315. package/dist/server/subscriptions.js +114 -0
  316. package/package.json +124 -0
@@ -0,0 +1,46 @@
1
+ const DEFAULT_SPARK_CHARS = " .:-=+*#%@";
2
+ function clamp(value, min, max) {
3
+ return Math.min(max, Math.max(min, value));
4
+ }
5
+ export function toSparkline(values, width = values.length, chars = DEFAULT_SPARK_CHARS) {
6
+ const points = values.filter((value) => Number.isFinite(value));
7
+ if (points.length === 0)
8
+ return "(no data)";
9
+ if (width <= 0)
10
+ return "";
11
+ if (chars.length < 2) {
12
+ throw new Error("Sparkline character set must contain at least 2 chars");
13
+ }
14
+ const sampled = points.length <= width
15
+ ? points
16
+ : width === 1
17
+ ? [points[points.length - 1]]
18
+ : Array.from({ length: width }, (_, index) => {
19
+ const sourceIndex = Math.round((index * (points.length - 1)) / (width - 1));
20
+ return points[sourceIndex];
21
+ });
22
+ const min = Math.min(...sampled);
23
+ const max = Math.max(...sampled);
24
+ const span = max - min;
25
+ if (span === 0) {
26
+ return chars[Math.floor(chars.length / 2)].repeat(sampled.length);
27
+ }
28
+ return sampled
29
+ .map((point) => {
30
+ const normalized = (point - min) / span;
31
+ const charIndex = clamp(Math.round(normalized * (chars.length - 1)), 0, chars.length - 1);
32
+ return chars[charIndex];
33
+ })
34
+ .join("");
35
+ }
36
+ export function toBar(value, max, width = 20, fillChar = "#", emptyChar = ".") {
37
+ if (width <= 0)
38
+ return "";
39
+ if (fillChar.length === 0 || emptyChar.length === 0) {
40
+ throw new Error("Bar characters must be non-empty");
41
+ }
42
+ const safeMax = max <= 0 ? 1 : max;
43
+ const ratio = clamp(value / safeMax, 0, 1);
44
+ const filled = Math.round(ratio * width);
45
+ return fillChar.repeat(filled) + emptyChar.repeat(width - filled);
46
+ }
@@ -0,0 +1,5 @@
1
+ export { AppShell, type AppShellProps, getToneTextColor } from "./AppShell.js";
2
+ export { Panel, type PanelProps } from "./Panel.js";
3
+ export { MetricStrip, type MetricStripProps } from "./MetricStrip.js";
4
+ export { toSparkline, toBar } from "./ascii.js";
5
+ export type { Tone, StatusChip, ShortcutHint, Metric } from "./types.js";
@@ -0,0 +1,4 @@
1
+ export { AppShell, getToneTextColor } from "./AppShell.js";
2
+ export { Panel } from "./Panel.js";
3
+ export { MetricStrip } from "./MetricStrip.js";
4
+ export { toSparkline, toBar } from "./ascii.js";
@@ -0,0 +1,15 @@
1
+ export type Tone = "neutral" | "info" | "success" | "warning" | "danger";
2
+ export interface StatusChip {
3
+ label: string;
4
+ tone?: Tone;
5
+ }
6
+ export interface ShortcutHint {
7
+ key: string;
8
+ label: string;
9
+ }
10
+ export interface Metric {
11
+ label: string;
12
+ value: string;
13
+ tone?: Tone;
14
+ delta?: string;
15
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ export interface PnLProps {
3
+ value: number | string;
4
+ showSign?: boolean;
5
+ decimals?: number;
6
+ }
7
+ export declare function PnL({ value, showSign, decimals }: PnLProps): React.ReactElement;
8
+ export interface PnLPercentProps {
9
+ value: number | string;
10
+ decimals?: number;
11
+ }
12
+ export declare function PnLPercent({ value, decimals }: PnLPercentProps): React.ReactElement;
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Text } from "ink";
3
+ import { getPnLColor } from "../theme.js";
4
+ export function PnL({ value, showSign = true, decimals = 2 }) {
5
+ const numValue = typeof value === "string" ? parseFloat(value) : value;
6
+ if (isNaN(numValue)) {
7
+ return _jsx(Text, { color: "gray", children: "-" });
8
+ }
9
+ const color = getPnLColor(numValue);
10
+ const sign = showSign && numValue > 0 ? "+" : "";
11
+ const formatted = `${sign}${numValue.toFixed(decimals)}`;
12
+ return _jsx(Text, { color: color, children: formatted });
13
+ }
14
+ export function PnLPercent({ value, decimals = 2 }) {
15
+ const numValue = typeof value === "string" ? parseFloat(value) : value;
16
+ if (isNaN(numValue)) {
17
+ return _jsx(Text, { color: "gray", children: "-" });
18
+ }
19
+ const color = getPnLColor(numValue);
20
+ const sign = numValue > 0 ? "+" : "";
21
+ const formatted = `${sign}${numValue.toFixed(decimals)}%`;
22
+ return _jsx(Text, { color: color, children: formatted });
23
+ }
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ export interface SpinnerProps {
3
+ label?: string;
4
+ }
5
+ export declare function Spinner({ label }: SpinnerProps): React.ReactElement;
6
+ export interface ErrorDisplayProps {
7
+ message: string;
8
+ }
9
+ export declare function ErrorDisplay({ message }: ErrorDisplayProps): React.ReactElement;
10
+ export interface SuccessDisplayProps {
11
+ message: string;
12
+ }
13
+ export declare function SuccessDisplay({ message }: SuccessDisplayProps): React.ReactElement;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import InkSpinner from "ink-spinner";
4
+ import { colors } from "../theme.js";
5
+ export function Spinner({ label = "Loading..." }) {
6
+ return (_jsxs(Box, { children: [_jsx(Text, { color: colors.info, children: _jsx(InkSpinner, { type: "dots" }) }), _jsxs(Text, { children: [" ", label] })] }));
7
+ }
8
+ export function ErrorDisplay({ message }) {
9
+ return (_jsx(Box, { children: _jsxs(Text, { color: colors.loss, children: ["Error: ", message] }) }));
10
+ }
11
+ export function SuccessDisplay({ message }) {
12
+ return (_jsx(Box, { children: _jsx(Text, { color: colors.profit, children: message }) }));
13
+ }
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ export interface Column<T> {
3
+ key: keyof T;
4
+ header: string;
5
+ width?: number;
6
+ align?: "left" | "right";
7
+ render?: (value: T[keyof T], row: T) => React.ReactNode;
8
+ }
9
+ export interface TableProps<T> {
10
+ data: T[];
11
+ columns: Column<T>[];
12
+ emptyMessage?: string;
13
+ }
14
+ export declare function Table<T extends object>({ data, columns, emptyMessage, }: TableProps<T>): React.ReactElement;
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { colors } from "../theme.js";
4
+ function calculateColumnWidths(data, columns) {
5
+ const widths = new Map();
6
+ for (const col of columns) {
7
+ if (col.width) {
8
+ widths.set(col.key, col.width);
9
+ continue;
10
+ }
11
+ let maxWidth = col.header.length;
12
+ for (const row of data) {
13
+ const value = row[col.key];
14
+ const strValue = value === null || value === undefined ? "" : String(value);
15
+ maxWidth = Math.max(maxWidth, strValue.length);
16
+ }
17
+ widths.set(col.key, maxWidth);
18
+ }
19
+ return widths;
20
+ }
21
+ function padValue(value, width, align) {
22
+ if (align === "right") {
23
+ return value.padStart(width);
24
+ }
25
+ return value.padEnd(width);
26
+ }
27
+ export function Table({ data, columns, emptyMessage = "No data", }) {
28
+ if (data.length === 0) {
29
+ return (_jsx(Box, { children: _jsx(Text, { color: colors.muted, children: emptyMessage }) }));
30
+ }
31
+ const widths = calculateColumnWidths(data, columns);
32
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: columns.map((col, i) => (_jsx(Box, { marginRight: i < columns.length - 1 ? 2 : 0, children: _jsx(Text, { color: colors.header, bold: true, children: padValue(col.header, widths.get(col.key) || col.header.length, col.align || "left") }) }, String(col.key)))) }), _jsx(Box, { children: columns.map((col, i) => (_jsx(Box, { marginRight: i < columns.length - 1 ? 2 : 0, children: _jsx(Text, { color: colors.muted, children: "-".repeat(widths.get(col.key) || col.header.length) }) }, String(col.key)))) }), data.map((row, rowIndex) => (_jsx(Box, { children: columns.map((col, colIndex) => {
33
+ const value = row[col.key];
34
+ const width = widths.get(col.key) || col.header.length;
35
+ const align = col.align || "left";
36
+ if (col.render) {
37
+ return (_jsx(Box, { marginRight: colIndex < columns.length - 1 ? 2 : 0, children: _jsx(Box, { width: width, justifyContent: align === "right" ? "flex-end" : "flex-start", children: col.render(value, row) }) }, String(col.key)));
38
+ }
39
+ const strValue = value === null || value === undefined ? "" : String(value);
40
+ return (_jsx(Box, { marginRight: colIndex < columns.length - 1 ? 2 : 0, children: _jsx(Text, { children: padValue(strValue, width, align) }) }, String(col.key)));
41
+ }) }, rowIndex)))] }));
42
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ export interface WatchHeaderProps {
3
+ title: string;
4
+ lastUpdated?: Date;
5
+ }
6
+ export declare function WatchHeader({ title, lastUpdated }: WatchHeaderProps): React.ReactElement;
7
+ export interface WatchFooterProps {
8
+ message?: string;
9
+ }
10
+ export declare function WatchFooter({ message }: WatchFooterProps): React.ReactElement;
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { colors } from "../theme.js";
4
+ import { formatTimestamp } from "../../watch.js";
5
+ export function WatchHeader({ title, lastUpdated }) {
6
+ const timestamp = lastUpdated
7
+ ? lastUpdated.toLocaleTimeString("en-US", {
8
+ hour12: false,
9
+ hour: "2-digit",
10
+ minute: "2-digit",
11
+ second: "2-digit",
12
+ })
13
+ : formatTimestamp();
14
+ return (_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, children: title }), _jsx(Text, { color: colors.muted, children: " (watching)" }), _jsx(Box, { flexGrow: 1 }), _jsxs(Text, { color: colors.muted, children: ["Last updated: ", timestamp] })] }));
15
+ }
16
+ export function WatchFooter({ message = "Press Ctrl+C to exit" }) {
17
+ return (_jsx(Box, { marginTop: 1, children: _jsx(Text, { color: colors.muted, children: message }) }));
18
+ }
@@ -0,0 +1,4 @@
1
+ export { Table, type Column, type TableProps } from "./Table.js";
2
+ export { PnL, PnLPercent, type PnLProps, type PnLPercentProps } from "./PnL.js";
3
+ export { WatchHeader, WatchFooter, type WatchHeaderProps, type WatchFooterProps } from "./WatchHeader.js";
4
+ export { Spinner, ErrorDisplay, SuccessDisplay, type SpinnerProps, type ErrorDisplayProps, type SuccessDisplayProps } from "./Spinner.js";
@@ -0,0 +1,4 @@
1
+ export { Table } from "./Table.js";
2
+ export { PnL, PnLPercent } from "./PnL.js";
3
+ export { WatchHeader, WatchFooter } from "./WatchHeader.js";
4
+ export { Spinner, ErrorDisplay, SuccessDisplay } from "./Spinner.js";
@@ -0,0 +1,4 @@
1
+ export * from "./theme.js";
2
+ export * from "./render.js";
3
+ export * from "./components/index.js";
4
+ export * from "./app/index.js";
@@ -0,0 +1,4 @@
1
+ export * from "./theme.js";
2
+ export * from "./render.js";
3
+ export * from "./components/index.js";
4
+ export * from "./app/index.js";
@@ -0,0 +1,12 @@
1
+ import React from "react";
2
+ import { type Instance } from "ink";
3
+ /**
4
+ * Render a React component to the terminal using Ink
5
+ * Returns the instance for cleanup
6
+ */
7
+ export declare function render(element: React.ReactElement): Instance;
8
+ /**
9
+ * Render a component for watch mode (persistent)
10
+ * Returns cleanup function that restores cursor visibility
11
+ */
12
+ export declare function renderWatch(element: React.ReactElement): () => void;
@@ -0,0 +1,21 @@
1
+ import { render as inkRender } from "ink";
2
+ import { showCursor } from "../watch.js";
3
+ /**
4
+ * Render a React component to the terminal using Ink
5
+ * Returns the instance for cleanup
6
+ */
7
+ export function render(element) {
8
+ return inkRender(element);
9
+ }
10
+ /**
11
+ * Render a component for watch mode (persistent)
12
+ * Returns cleanup function that restores cursor visibility
13
+ */
14
+ export function renderWatch(element) {
15
+ const { unmount, clear } = inkRender(element);
16
+ return () => {
17
+ clear();
18
+ unmount();
19
+ showCursor();
20
+ };
21
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Color theme for CLI output
3
+ *
4
+ * Ink color names — Ink respects NO_COLOR internally.
5
+ * For non-Ink ANSI output, use highlighter from experience.ts.
6
+ */
7
+ export declare const colors: {
8
+ readonly profit: "green";
9
+ readonly loss: "red";
10
+ readonly neutral: "white";
11
+ readonly muted: "gray";
12
+ readonly header: "cyan";
13
+ readonly warning: "yellow";
14
+ readonly info: "blue";
15
+ };
16
+ export type ThemeColor = (typeof colors)[keyof typeof colors];
17
+ /**
18
+ * Get the appropriate color for a PnL value
19
+ */
20
+ export declare function getPnLColor(value: number): ThemeColor;
21
+ /**
22
+ * Get the appropriate color for a percentage change
23
+ */
24
+ export declare function getChangeColor(value: number): ThemeColor;
25
+ /**
26
+ * Theme configuration for @inquirer/prompts
27
+ * Re-exported from lib/ui-tokens.ts (single source of truth).
28
+ */
29
+ export { inquirerTheme } from "../../lib/ui-tokens.js";
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Color theme for CLI output
3
+ *
4
+ * Ink color names — Ink respects NO_COLOR internally.
5
+ * For non-Ink ANSI output, use highlighter from experience.ts.
6
+ */
7
+ export const colors = {
8
+ profit: "green",
9
+ loss: "red",
10
+ neutral: "white",
11
+ muted: "gray",
12
+ header: "cyan",
13
+ warning: "yellow",
14
+ info: "blue",
15
+ };
16
+ /**
17
+ * Get the appropriate color for a PnL value
18
+ */
19
+ export function getPnLColor(value) {
20
+ if (value > 0)
21
+ return colors.profit;
22
+ if (value < 0)
23
+ return colors.loss;
24
+ return colors.neutral;
25
+ }
26
+ /**
27
+ * Get the appropriate color for a percentage change
28
+ */
29
+ export function getChangeColor(value) {
30
+ if (value > 0)
31
+ return colors.profit;
32
+ if (value < 0)
33
+ return colors.loss;
34
+ return colors.neutral;
35
+ }
36
+ /**
37
+ * Theme configuration for @inquirer/prompts
38
+ * Re-exported from lib/ui-tokens.ts (single source of truth).
39
+ */
40
+ export { inquirerTheme } from "../../lib/ui-tokens.js";
@@ -0,0 +1,10 @@
1
+ import type { Command } from "commander";
2
+ import { type CommandIntent } from "./command-metadata.js";
3
+ export declare function commandPathFromCommand(command: Command): string[];
4
+ export declare function classifyCommandIntentFromPath(path: string[]): CommandIntent;
5
+ export declare function resolveTestnetMode(args: {
6
+ argv: string[];
7
+ commandPath: string[];
8
+ exchangeNetworkOverride?: "testnet" | "mainnet";
9
+ fallbackTestnet?: boolean;
10
+ }): boolean;
@@ -0,0 +1,35 @@
1
+ import { resolveNetworkDecision } from "../lib/network-model.js";
2
+ import { classifyCommandIntentFromMetadata, } from "./command-metadata.js";
3
+ function hasCliFlag(argv, flag) {
4
+ return argv.some((arg) => arg === flag);
5
+ }
6
+ export function commandPathFromCommand(command) {
7
+ const path = [];
8
+ let current = command;
9
+ while (current) {
10
+ const name = current.name().trim().toLowerCase();
11
+ if (name && name !== "perps") {
12
+ path.unshift(name);
13
+ }
14
+ current = current.parent;
15
+ }
16
+ return path;
17
+ }
18
+ export function classifyCommandIntentFromPath(path) {
19
+ return classifyCommandIntentFromMetadata(path);
20
+ }
21
+ export function resolveTestnetMode(args) {
22
+ const hasTestnet = hasCliFlag(args.argv, "--testnet");
23
+ const hasMainnet = hasCliFlag(args.argv, "--mainnet");
24
+ if (hasTestnet && hasMainnet) {
25
+ throw new Error("Cannot use --testnet and --mainnet together");
26
+ }
27
+ const intent = classifyCommandIntentFromPath(args.commandPath);
28
+ const decision = resolveNetworkDecision({
29
+ intent,
30
+ cliOverride: hasTestnet ? "testnet" : hasMainnet ? "mainnet" : undefined,
31
+ exchangeOverride: args.exchangeNetworkOverride,
32
+ fallbackNetwork: args.fallbackTestnet ? "testnet" : "mainnet",
33
+ });
34
+ return decision.network === "testnet";
35
+ }
@@ -0,0 +1,11 @@
1
+ export interface OutputOptions {
2
+ json: boolean;
3
+ }
4
+ export declare function output(data: unknown, options: OutputOptions): void;
5
+ export declare function outputError(message: string): void;
6
+ export declare function outputSuccess(message: string): void;
7
+ /**
8
+ * Format an array of objects as a table string (for watch mode display)
9
+ * Returns the formatted string instead of printing to console
10
+ */
11
+ export declare function formatArrayAsTable(arr: unknown[]): string;
@@ -0,0 +1,115 @@
1
+ import { formatStatusLine, stripAnsi } from "./experience.js";
2
+ export function output(data, options) {
3
+ if (options.json) {
4
+ console.log(JSON.stringify(data, null, 2));
5
+ }
6
+ else {
7
+ if (typeof data === "string") {
8
+ console.log(data);
9
+ }
10
+ else if (Array.isArray(data)) {
11
+ formatArray(data);
12
+ }
13
+ else if (typeof data === "object" && data !== null) {
14
+ formatObject(data);
15
+ }
16
+ else {
17
+ console.log(data);
18
+ }
19
+ }
20
+ }
21
+ function visibleLength(text) {
22
+ return stripAnsi(text).length;
23
+ }
24
+ function formatArray(arr) {
25
+ if (arr.length === 0) {
26
+ console.log("(empty)");
27
+ return;
28
+ }
29
+ const first = arr[0];
30
+ if (typeof first === "object" && first !== null) {
31
+ // Table format for array of objects
32
+ const keys = Object.keys(first);
33
+ const widths = keys.map((k) => Math.max(k.length, ...arr.map((item) => {
34
+ const val = item[k];
35
+ return visibleLength(String(val ?? ""));
36
+ })));
37
+ // Header
38
+ console.log(keys.map((k, i) => k.padEnd(widths[i])).join(" "));
39
+ console.log(widths.map((w) => "-".repeat(w)).join(" "));
40
+ // Rows
41
+ for (const item of arr) {
42
+ const row = keys.map((k, i) => {
43
+ const val = item[k];
44
+ const str = String(val ?? "");
45
+ const padding = widths[i] - visibleLength(str);
46
+ return str + " ".repeat(Math.max(0, padding));
47
+ });
48
+ console.log(row.join(" "));
49
+ }
50
+ }
51
+ else {
52
+ for (const item of arr) {
53
+ console.log(item);
54
+ }
55
+ }
56
+ }
57
+ function formatObject(obj, indent = 0) {
58
+ const prefix = " ".repeat(indent);
59
+ for (const [key, value] of Object.entries(obj)) {
60
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
61
+ console.log(`${prefix}${key}:`);
62
+ formatObject(value, indent + 1);
63
+ }
64
+ else if (Array.isArray(value)) {
65
+ console.log(`${prefix}${key}: [${value.length} items]`);
66
+ }
67
+ else {
68
+ console.log(`${prefix}${key}: ${value}`);
69
+ }
70
+ }
71
+ }
72
+ export function outputError(message) {
73
+ console.error(formatStatusLine("error", `Error: ${message}`, process.stderr));
74
+ }
75
+ export function outputSuccess(message) {
76
+ if (!process.stdout.isTTY) {
77
+ console.log(message);
78
+ return;
79
+ }
80
+ console.log(formatStatusLine("success", message));
81
+ }
82
+ /**
83
+ * Format an array of objects as a table string (for watch mode display)
84
+ * Returns the formatted string instead of printing to console
85
+ */
86
+ export function formatArrayAsTable(arr) {
87
+ if (arr.length === 0) {
88
+ return "(empty)";
89
+ }
90
+ const first = arr[0];
91
+ if (typeof first !== "object" || first === null) {
92
+ return arr.map(String).join("\n");
93
+ }
94
+ const keys = Object.keys(first);
95
+ const widths = keys.map((k) => Math.max(k.length, ...arr.map((item) => {
96
+ const val = item[k];
97
+ return visibleLength(String(val ?? ""));
98
+ })));
99
+ const lines = [];
100
+ // Header
101
+ lines.push(keys.map((k, i) => k.padEnd(widths[i])).join(" "));
102
+ // Separator
103
+ lines.push(widths.map((w) => "-".repeat(w)).join(" "));
104
+ // Rows
105
+ for (const item of arr) {
106
+ const row = keys.map((k, i) => {
107
+ const val = item[k];
108
+ const str = String(val ?? "");
109
+ const padding = widths[i] - visibleLength(str);
110
+ return str + " ".repeat(Math.max(0, padding));
111
+ });
112
+ lines.push(row.join(" "));
113
+ }
114
+ return lines.join("\n");
115
+ }
@@ -0,0 +1,18 @@
1
+ import { Command } from "commander";
2
+ import { type CLIContext } from "./context.js";
3
+ export interface GlobalOptions {
4
+ json: boolean;
5
+ testnet: boolean;
6
+ mainnet: boolean;
7
+ exchange: string;
8
+ banner: boolean;
9
+ human: boolean;
10
+ verbose: boolean;
11
+ }
12
+ export declare function createProgram(): Command;
13
+ export declare function getContext(command: Command): CLIContext;
14
+ export declare function getOutputOptions(command: Command): {
15
+ json: boolean;
16
+ };
17
+ export declare function getSelectedExchange(command: Command): string;
18
+ export declare function getVerbose(command: Command): boolean;