openbroker 1.3.2 → 1.5.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 (169) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/auto/audit.d.ts +57 -0
  3. package/dist/auto/audit.d.ts.map +1 -0
  4. package/dist/auto/audit.js +407 -0
  5. package/dist/auto/cli.d.ts +2 -0
  6. package/dist/auto/cli.d.ts.map +1 -0
  7. package/dist/auto/cli.js +423 -0
  8. package/dist/auto/events.d.ts +11 -0
  9. package/dist/auto/events.d.ts.map +1 -0
  10. package/dist/auto/events.js +36 -0
  11. package/dist/auto/examples/dca.d.ts +4 -0
  12. package/dist/auto/examples/dca.d.ts.map +1 -0
  13. package/dist/auto/examples/dca.js +60 -0
  14. package/dist/auto/examples/funding-arb.d.ts +4 -0
  15. package/dist/auto/examples/funding-arb.d.ts.map +1 -0
  16. package/dist/auto/examples/funding-arb.js +81 -0
  17. package/dist/auto/examples/grid.d.ts +4 -0
  18. package/dist/auto/examples/grid.d.ts.map +1 -0
  19. package/dist/auto/examples/grid.js +114 -0
  20. package/dist/auto/examples/mm-maker.d.ts +4 -0
  21. package/dist/auto/examples/mm-maker.d.ts.map +1 -0
  22. package/dist/auto/examples/mm-maker.js +131 -0
  23. package/dist/auto/examples/mm-spread.d.ts +4 -0
  24. package/dist/auto/examples/mm-spread.d.ts.map +1 -0
  25. package/dist/auto/examples/mm-spread.js +119 -0
  26. package/dist/auto/examples/price-alert.d.ts +4 -0
  27. package/dist/auto/examples/price-alert.d.ts.map +1 -0
  28. package/dist/auto/examples/price-alert.js +85 -0
  29. package/dist/auto/keep-awake.d.ts +11 -0
  30. package/dist/auto/keep-awake.d.ts.map +1 -0
  31. package/dist/auto/keep-awake.js +70 -0
  32. package/dist/auto/loader.d.ts +22 -0
  33. package/dist/auto/loader.d.ts.map +1 -0
  34. package/dist/auto/loader.js +127 -0
  35. package/dist/auto/prune.d.ts +40 -0
  36. package/dist/auto/prune.d.ts.map +1 -0
  37. package/dist/auto/prune.js +204 -0
  38. package/dist/auto/registry.d.ts +24 -0
  39. package/dist/auto/registry.d.ts.map +1 -0
  40. package/dist/auto/registry.js +93 -0
  41. package/dist/auto/report.d.ts +3 -0
  42. package/dist/auto/report.d.ts.map +1 -0
  43. package/dist/auto/report.js +385 -0
  44. package/dist/auto/runtime.d.ts +33 -0
  45. package/dist/auto/runtime.d.ts.map +1 -0
  46. package/dist/auto/runtime.js +844 -0
  47. package/dist/auto/types.d.ts +236 -0
  48. package/dist/auto/types.d.ts.map +1 -0
  49. package/dist/auto/types.js +3 -0
  50. package/dist/core/client.d.ts +691 -0
  51. package/dist/core/client.d.ts.map +1 -0
  52. package/dist/core/client.js +2061 -0
  53. package/dist/core/config.d.ts +22 -0
  54. package/dist/core/config.d.ts.map +1 -0
  55. package/dist/core/config.js +143 -0
  56. package/dist/core/types.d.ts +228 -0
  57. package/dist/core/types.d.ts.map +1 -0
  58. package/dist/core/types.js +2 -0
  59. package/dist/core/utils.d.ts +61 -0
  60. package/dist/core/utils.d.ts.map +1 -0
  61. package/dist/core/utils.js +142 -0
  62. package/dist/core/ws.d.ts +121 -0
  63. package/dist/core/ws.d.ts.map +1 -0
  64. package/dist/core/ws.js +222 -0
  65. package/dist/info/account.d.ts +3 -0
  66. package/dist/info/account.d.ts.map +1 -0
  67. package/dist/info/account.js +198 -0
  68. package/dist/info/all-markets.d.ts +3 -0
  69. package/dist/info/all-markets.d.ts.map +1 -0
  70. package/dist/info/all-markets.js +272 -0
  71. package/dist/info/candles.d.ts +3 -0
  72. package/dist/info/candles.d.ts.map +1 -0
  73. package/dist/info/candles.js +120 -0
  74. package/dist/info/fees.d.ts +3 -0
  75. package/dist/info/fees.d.ts.map +1 -0
  76. package/dist/info/fees.js +87 -0
  77. package/dist/info/fills.d.ts +3 -0
  78. package/dist/info/fills.d.ts.map +1 -0
  79. package/dist/info/fills.js +105 -0
  80. package/dist/info/funding-history.d.ts +3 -0
  81. package/dist/info/funding-history.d.ts.map +1 -0
  82. package/dist/info/funding-history.js +98 -0
  83. package/dist/info/funding-scan.d.ts +3 -0
  84. package/dist/info/funding-scan.d.ts.map +1 -0
  85. package/dist/info/funding-scan.js +178 -0
  86. package/dist/info/funding.d.ts +3 -0
  87. package/dist/info/funding.d.ts.map +1 -0
  88. package/dist/info/funding.js +158 -0
  89. package/dist/info/markets.d.ts +3 -0
  90. package/dist/info/markets.d.ts.map +1 -0
  91. package/dist/info/markets.js +178 -0
  92. package/dist/info/order-status.d.ts +3 -0
  93. package/dist/info/order-status.d.ts.map +1 -0
  94. package/dist/info/order-status.js +85 -0
  95. package/dist/info/orders.d.ts +3 -0
  96. package/dist/info/orders.d.ts.map +1 -0
  97. package/dist/info/orders.js +162 -0
  98. package/dist/info/outcomes.d.ts +3 -0
  99. package/dist/info/outcomes.d.ts.map +1 -0
  100. package/dist/info/outcomes.js +175 -0
  101. package/dist/info/positions.d.ts +3 -0
  102. package/dist/info/positions.d.ts.map +1 -0
  103. package/dist/info/positions.js +127 -0
  104. package/dist/info/rate-limit.d.ts +3 -0
  105. package/dist/info/rate-limit.d.ts.map +1 -0
  106. package/dist/info/rate-limit.js +58 -0
  107. package/dist/info/search-markets.d.ts +3 -0
  108. package/dist/info/search-markets.d.ts.map +1 -0
  109. package/dist/info/search-markets.js +296 -0
  110. package/dist/info/spot.d.ts +3 -0
  111. package/dist/info/spot.d.ts.map +1 -0
  112. package/dist/info/spot.js +192 -0
  113. package/dist/info/trades.d.ts +3 -0
  114. package/dist/info/trades.d.ts.map +1 -0
  115. package/dist/info/trades.js +97 -0
  116. package/dist/lib.d.ts +14 -0
  117. package/dist/lib.d.ts.map +1 -0
  118. package/dist/lib.js +17 -0
  119. package/dist/operations/bracket.d.ts +28 -0
  120. package/dist/operations/bracket.d.ts.map +1 -0
  121. package/dist/operations/bracket.js +266 -0
  122. package/dist/operations/cancel.d.ts +3 -0
  123. package/dist/operations/cancel.d.ts.map +1 -0
  124. package/dist/operations/cancel.js +107 -0
  125. package/dist/operations/chase.d.ts +25 -0
  126. package/dist/operations/chase.d.ts.map +1 -0
  127. package/dist/operations/chase.js +215 -0
  128. package/dist/operations/limit-order.d.ts +3 -0
  129. package/dist/operations/limit-order.d.ts.map +1 -0
  130. package/dist/operations/limit-order.js +144 -0
  131. package/dist/operations/market-order.d.ts +3 -0
  132. package/dist/operations/market-order.d.ts.map +1 -0
  133. package/dist/operations/market-order.js +153 -0
  134. package/dist/operations/outcome-order.d.ts +3 -0
  135. package/dist/operations/outcome-order.d.ts.map +1 -0
  136. package/dist/operations/outcome-order.js +171 -0
  137. package/dist/operations/scale.d.ts +3 -0
  138. package/dist/operations/scale.d.ts.map +1 -0
  139. package/dist/operations/scale.js +212 -0
  140. package/dist/operations/set-tpsl.d.ts +3 -0
  141. package/dist/operations/set-tpsl.d.ts.map +1 -0
  142. package/dist/operations/set-tpsl.js +277 -0
  143. package/dist/operations/spot-order.d.ts +3 -0
  144. package/dist/operations/spot-order.d.ts.map +1 -0
  145. package/dist/operations/spot-order.js +173 -0
  146. package/dist/operations/trigger-order.d.ts +3 -0
  147. package/dist/operations/trigger-order.d.ts.map +1 -0
  148. package/dist/operations/trigger-order.js +177 -0
  149. package/dist/operations/twap-cancel.d.ts +3 -0
  150. package/dist/operations/twap-cancel.d.ts.map +1 -0
  151. package/dist/operations/twap-cancel.js +57 -0
  152. package/dist/operations/twap-status.d.ts +3 -0
  153. package/dist/operations/twap-status.d.ts.map +1 -0
  154. package/dist/operations/twap-status.js +81 -0
  155. package/dist/operations/twap.d.ts +3 -0
  156. package/dist/operations/twap.d.ts.map +1 -0
  157. package/dist/operations/twap.js +124 -0
  158. package/dist/setup/approve-builder.d.ts +3 -0
  159. package/dist/setup/approve-builder.d.ts.map +1 -0
  160. package/dist/setup/approve-builder.js +155 -0
  161. package/dist/setup/env.d.ts +4 -0
  162. package/dist/setup/env.d.ts.map +1 -0
  163. package/dist/setup/env.js +8 -0
  164. package/dist/setup/onboard.d.ts +10 -0
  165. package/dist/setup/onboard.d.ts.map +1 -0
  166. package/dist/setup/onboard.js +462 -0
  167. package/package.json +10 -4
  168. package/scripts/core/client.ts +19 -1
  169. package/scripts/core/types.ts +7 -0
@@ -0,0 +1,385 @@
1
+ #!/usr/bin/env node
2
+ import { DatabaseSync } from 'node:sqlite';
3
+ import { AUDIT_DB_PATH } from './audit.js';
4
+ import { formatUsd, parseArgs } from '../core/utils.js';
5
+ const DEFAULT_WATCH_INTERVAL_MS = 2000;
6
+ function printUsage() {
7
+ console.log(`
8
+ Usage: openbroker auto report <id> [options]
9
+
10
+ Options:
11
+ --run <run-id|latest> Specific run ID to inspect (default: latest)
12
+ --limit <n> Number of recent rows per section (default: 10)
13
+ --watch Refresh the report continuously
14
+ --watch-interval <ms> Refresh interval for --watch (default: 2000)
15
+ --json Output JSON
16
+ --help, -h Show this help
17
+
18
+ Examples:
19
+ openbroker auto report hype-mm-v2-live-r4
20
+ openbroker auto report hype-mm-v2-live-r4 --limit 20
21
+ openbroker auto report hype-mm-v2-live-r4 --watch
22
+ openbroker auto report hype-mm-v2-live-r4 --run 123e4567... --json
23
+ `);
24
+ }
25
+ function parseJson(value) {
26
+ if (!value)
27
+ return null;
28
+ try {
29
+ return JSON.parse(value);
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ function parseNumber(raw, fallback) {
36
+ const parsed = Number(raw);
37
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
38
+ }
39
+ function formatTimestamp(timestamp) {
40
+ return timestamp ? new Date(timestamp).toLocaleString() : '-';
41
+ }
42
+ function formatDurationMs(startedAt, stoppedAt) {
43
+ const end = stoppedAt ?? Date.now();
44
+ const totalSeconds = Math.max(0, Math.round((end - startedAt) / 1000));
45
+ const hours = Math.floor(totalSeconds / 3600);
46
+ const minutes = Math.floor((totalSeconds % 3600) / 60);
47
+ const seconds = totalSeconds % 60;
48
+ if (hours > 0)
49
+ return `${hours}h ${minutes}m ${seconds}s`;
50
+ if (minutes > 0)
51
+ return `${minutes}m ${seconds}s`;
52
+ return `${seconds}s`;
53
+ }
54
+ function getPositionalArgs(rawArgs) {
55
+ return rawArgs.filter((arg, index) => {
56
+ if (arg.startsWith('--'))
57
+ return false;
58
+ if (index > 0 && rawArgs[index - 1]?.startsWith('--'))
59
+ return false;
60
+ return true;
61
+ });
62
+ }
63
+ function loadReport(db, automationId, runSelector, limit) {
64
+ const run = runSelector !== 'latest'
65
+ ? db.prepare(`
66
+ SELECT *
67
+ FROM automation_runs
68
+ WHERE automation_id = ? AND run_id = ?
69
+ LIMIT 1
70
+ `).get(automationId, runSelector)
71
+ : db.prepare(`
72
+ SELECT *
73
+ FROM automation_runs
74
+ WHERE automation_id = ?
75
+ ORDER BY started_at DESC
76
+ LIMIT 1
77
+ `).get(automationId);
78
+ if (!run) {
79
+ throw new Error(`No audit run found for automation "${automationId}"${runSelector !== 'latest' ? ` and run "${runSelector}"` : ''}`);
80
+ }
81
+ const countTables = {
82
+ logs: 'automation_logs',
83
+ events: 'automation_events',
84
+ actions: 'automation_actions',
85
+ snapshots: 'automation_snapshots',
86
+ orderUpdates: 'automation_order_updates',
87
+ fills: 'automation_fills',
88
+ userEvents: 'automation_user_events',
89
+ stateChanges: 'automation_state_changes',
90
+ publishes: 'automation_publishes',
91
+ errors: 'automation_errors',
92
+ notes: 'automation_notes',
93
+ metrics: 'automation_metrics',
94
+ };
95
+ const counts = Object.fromEntries(Object.entries(countTables).map(([key, table]) => {
96
+ const row = db.prepare(`SELECT count(*) AS c FROM ${table} WHERE run_id = ?`).get(run.run_id);
97
+ return [key, row.c];
98
+ }));
99
+ const fillSummary = db.prepare(`
100
+ SELECT
101
+ count(*) AS count,
102
+ COALESCE(sum(fee), 0) AS total_fee,
103
+ COALESCE(sum(closed_pnl), 0) AS total_closed_pnl,
104
+ COALESCE(sum(size * price), 0) AS total_volume
105
+ FROM automation_fills
106
+ WHERE run_id = ?
107
+ `).get(run.run_id);
108
+ const firstSnapshot = db.prepare(`
109
+ SELECT timestamp, poll_count, equity, margin_used, margin_used_pct, positions_json
110
+ FROM automation_snapshots
111
+ WHERE run_id = ?
112
+ ORDER BY timestamp ASC
113
+ LIMIT 1
114
+ `).get(run.run_id);
115
+ const latestSnapshot = db.prepare(`
116
+ SELECT timestamp, poll_count, equity, margin_used, margin_used_pct, positions_json
117
+ FROM automation_snapshots
118
+ WHERE run_id = ?
119
+ ORDER BY timestamp DESC
120
+ LIMIT 1
121
+ `).get(run.run_id);
122
+ const actionBreakdown = db.prepare(`
123
+ SELECT
124
+ method,
125
+ sum(CASE WHEN phase = 'request' THEN 1 ELSE 0 END) AS requests,
126
+ sum(CASE WHEN phase = 'response' THEN 1 ELSE 0 END) AS responses,
127
+ sum(CASE WHEN phase = 'error' THEN 1 ELSE 0 END) AS errors
128
+ FROM automation_actions
129
+ WHERE run_id = ?
130
+ GROUP BY method
131
+ ORDER BY requests DESC, responses DESC, errors DESC, method ASC
132
+ `).all(run.run_id);
133
+ const recentLogs = db.prepare(`
134
+ SELECT timestamp, level, message
135
+ FROM automation_logs
136
+ WHERE run_id = ?
137
+ ORDER BY timestamp DESC
138
+ LIMIT ?
139
+ `).all(run.run_id, limit);
140
+ const recentErrors = db.prepare(`
141
+ SELECT timestamp, stage, error_json
142
+ FROM automation_errors
143
+ WHERE run_id = ?
144
+ ORDER BY timestamp DESC
145
+ LIMIT ?
146
+ `).all(run.run_id, limit);
147
+ const recentFills = db.prepare(`
148
+ SELECT timestamp, coin, side, size, price, fee, closed_pnl
149
+ FROM automation_fills
150
+ WHERE run_id = ?
151
+ ORDER BY timestamp DESC
152
+ LIMIT ?
153
+ `).all(run.run_id, limit);
154
+ const recentOrderUpdates = db.prepare(`
155
+ SELECT timestamp, coin, side, size, price, status, oid
156
+ FROM automation_order_updates
157
+ WHERE run_id = ?
158
+ ORDER BY timestamp DESC
159
+ LIMIT ?
160
+ `).all(run.run_id, limit);
161
+ const recentNotes = db.prepare(`
162
+ SELECT timestamp, kind, payload_json
163
+ FROM automation_notes
164
+ WHERE run_id = ?
165
+ ORDER BY timestamp DESC
166
+ LIMIT ?
167
+ `).all(run.run_id, limit);
168
+ const recentMetrics = db.prepare(`
169
+ SELECT timestamp, name, value, tags_json
170
+ FROM automation_metrics
171
+ WHERE run_id = ?
172
+ ORDER BY timestamp DESC
173
+ LIMIT ?
174
+ `).all(run.run_id, limit);
175
+ const report = {
176
+ automationId: run.automation_id,
177
+ runId: run.run_id,
178
+ status: run.status,
179
+ stopReason: run.stop_reason,
180
+ scriptPath: run.script_path,
181
+ startedAt: new Date(run.started_at).toISOString(),
182
+ stoppedAt: run.stopped_at ? new Date(run.stopped_at).toISOString() : null,
183
+ durationSec: Math.max(0, Math.round(((run.stopped_at ?? Date.now()) - run.started_at) / 1000)),
184
+ accountAddress: run.account_address,
185
+ walletAddress: run.wallet_address,
186
+ dryRun: run.dry_run === 1,
187
+ verbose: run.verbose === 1,
188
+ useWebSocket: run.use_websocket === 1,
189
+ pollIntervalMs: run.poll_interval_ms,
190
+ pid: run.pid,
191
+ initialState: parseJson(run.initial_state_json),
192
+ persistedState: parseJson(run.persisted_state_json),
193
+ runtimeStats: {
194
+ pollCount: run.poll_count,
195
+ eventsEmitted: run.events_emitted,
196
+ },
197
+ counts,
198
+ fills: {
199
+ count: fillSummary.count,
200
+ totalFees: fillSummary.total_fee,
201
+ totalClosedPnl: fillSummary.total_closed_pnl,
202
+ netAfterFees: fillSummary.total_closed_pnl - fillSummary.total_fee,
203
+ totalVolume: fillSummary.total_volume,
204
+ },
205
+ equity: {
206
+ first: firstSnapshot ? {
207
+ timestamp: firstSnapshot.timestamp,
208
+ pollCount: firstSnapshot.poll_count,
209
+ equity: firstSnapshot.equity,
210
+ marginUsed: firstSnapshot.margin_used,
211
+ marginUsedPct: firstSnapshot.margin_used_pct,
212
+ positions: parseJson(firstSnapshot.positions_json),
213
+ } : null,
214
+ latest: latestSnapshot ? {
215
+ timestamp: latestSnapshot.timestamp,
216
+ pollCount: latestSnapshot.poll_count,
217
+ equity: latestSnapshot.equity,
218
+ marginUsed: latestSnapshot.margin_used,
219
+ marginUsedPct: latestSnapshot.margin_used_pct,
220
+ positions: parseJson(latestSnapshot.positions_json),
221
+ } : null,
222
+ delta: firstSnapshot && latestSnapshot
223
+ ? Number(latestSnapshot.equity) - Number(firstSnapshot.equity)
224
+ : null,
225
+ },
226
+ actionBreakdown,
227
+ recent: {
228
+ logs: recentLogs,
229
+ errors: recentErrors.map((row) => ({
230
+ ...row,
231
+ error: parseJson(row.error_json),
232
+ })),
233
+ fills: recentFills,
234
+ orderUpdates: recentOrderUpdates,
235
+ notes: recentNotes.map((row) => ({
236
+ ...row,
237
+ payload: parseJson(row.payload_json),
238
+ })),
239
+ metrics: recentMetrics.map((row) => ({
240
+ ...row,
241
+ tags: parseJson(row.tags_json),
242
+ })),
243
+ },
244
+ };
245
+ return { run, report, counts, actionBreakdown, recentErrors, recentFills, recentLogs };
246
+ }
247
+ function renderTextReport(data, watchMode = false, watchIntervalMs = DEFAULT_WATCH_INTERVAL_MS) {
248
+ const { run, report, counts, actionBreakdown, recentErrors, recentFills, recentLogs } = data;
249
+ if (watchMode && process.stdout.isTTY) {
250
+ process.stdout.write('\x1Bc');
251
+ }
252
+ console.log('Open Broker - Automation Report');
253
+ console.log('===============================\n');
254
+ console.log(`Automation: ${report.automationId}`);
255
+ console.log(`Run ID: ${report.runId}`);
256
+ console.log(`Status: ${report.status}${report.stopReason ? ` (${report.stopReason})` : ''}`);
257
+ console.log(`Started: ${formatTimestamp(run.started_at)}`);
258
+ console.log(`Stopped: ${formatTimestamp(run.stopped_at)}`);
259
+ console.log(`Duration: ${formatDurationMs(run.started_at, run.stopped_at)}`);
260
+ console.log(`Script: ${run.script_path}`);
261
+ console.log(`Account: ${run.account_address ?? '-'}`);
262
+ console.log(`Mode: ${report.dryRun ? 'dry' : 'live'}${report.useWebSocket ? ', ws' : ', polling only'}`);
263
+ console.log(`Poll interval: ${run.poll_interval_ms ?? '-'} ms`);
264
+ if (watchMode) {
265
+ console.log(`Refresh: every ${watchIntervalMs} ms (Ctrl-C to stop)`);
266
+ }
267
+ console.log('\nCounts');
268
+ console.log('------');
269
+ for (const [key, value] of Object.entries(counts)) {
270
+ console.log(`${key.padEnd(14)} ${value}`);
271
+ }
272
+ console.log('\nEconomics');
273
+ console.log('---------');
274
+ console.log(`Fills: ${report.fills.count}`);
275
+ console.log(`Volume: ${formatUsd(report.fills.totalVolume)}`);
276
+ console.log(`Closed PnL: ${formatUsd(report.fills.totalClosedPnl)}`);
277
+ console.log(`Fees: ${formatUsd(report.fills.totalFees)}`);
278
+ console.log(`Net after fees: ${formatUsd(report.fills.netAfterFees)}`);
279
+ console.log('\nEquity');
280
+ console.log('------');
281
+ if (report.equity.first) {
282
+ console.log(`First snapshot: ${formatUsd(Number(report.equity.first.equity))} @ ${formatTimestamp(Number(report.equity.first.timestamp))}`);
283
+ }
284
+ else {
285
+ console.log('First snapshot: -');
286
+ }
287
+ if (report.equity.latest) {
288
+ console.log(`Latest snapshot:${formatUsd(Number(report.equity.latest.equity))} @ ${formatTimestamp(Number(report.equity.latest.timestamp))}`);
289
+ }
290
+ else {
291
+ console.log('Latest snapshot:-');
292
+ }
293
+ console.log(`Delta: ${report.equity.delta === null ? '-' : formatUsd(report.equity.delta)}`);
294
+ if (Array.isArray(actionBreakdown) && actionBreakdown.length > 0) {
295
+ console.log('\nActions');
296
+ console.log('-------');
297
+ for (const row of actionBreakdown) {
298
+ console.log(`${String(row.method).padEnd(20)} req=${String(row.requests).padStart(3)} resp=${String(row.responses).padStart(3)} err=${String(row.errors).padStart(3)}`);
299
+ }
300
+ }
301
+ if (recentErrors.length > 0) {
302
+ console.log('\nRecent Errors');
303
+ console.log('-------------');
304
+ for (const row of recentErrors) {
305
+ const parsed = parseJson(row.error_json);
306
+ console.log(`${formatTimestamp(Number(row.timestamp))} ${String(row.stage)} ${parsed?.message || String(row.error_json)}`);
307
+ }
308
+ }
309
+ if (recentFills.length > 0) {
310
+ console.log('\nRecent Fills');
311
+ console.log('------------');
312
+ for (const row of recentFills) {
313
+ console.log(`${formatTimestamp(Number(row.timestamp))} ${String(row.side).toUpperCase()} ${String(row.coin)} ${row.size} @ ${row.price} pnl=${row.closed_pnl} fee=${row.fee}`);
314
+ }
315
+ }
316
+ if (recentLogs.length > 0) {
317
+ console.log('\nRecent Logs');
318
+ console.log('-----------');
319
+ for (const row of recentLogs) {
320
+ console.log(`${formatTimestamp(Number(row.timestamp))} ${String(row.level).toUpperCase()} ${String(row.message)}`);
321
+ }
322
+ }
323
+ }
324
+ async function main() {
325
+ const rawArgs = process.argv.slice(2);
326
+ const args = parseArgs(rawArgs);
327
+ if (args.help || args.h) {
328
+ printUsage();
329
+ process.exit(0);
330
+ }
331
+ const positional = getPositionalArgs(rawArgs);
332
+ const automationId = positional[0];
333
+ if (!automationId) {
334
+ console.error('Error: automation ID is required');
335
+ printUsage();
336
+ process.exit(1);
337
+ }
338
+ const runSelector = String(args.run || 'latest');
339
+ const limit = parseNumber(args.limit, 10);
340
+ const jsonOutput = args.json === true;
341
+ const watchMode = args.watch === true;
342
+ const watchIntervalMs = parseNumber(args['watch-interval'], DEFAULT_WATCH_INTERVAL_MS);
343
+ if (watchMode && jsonOutput) {
344
+ console.error('Error: --watch cannot be combined with --json');
345
+ process.exit(1);
346
+ }
347
+ const db = new DatabaseSync(AUDIT_DB_PATH);
348
+ let stopRequested = false;
349
+ const cleanup = () => {
350
+ try {
351
+ db.close();
352
+ }
353
+ catch {
354
+ // ignore close failures during shutdown
355
+ }
356
+ };
357
+ const requestStop = () => {
358
+ stopRequested = true;
359
+ };
360
+ process.once('SIGINT', requestStop);
361
+ process.once('SIGTERM', requestStop);
362
+ try {
363
+ if (!watchMode) {
364
+ const data = loadReport(db, automationId, runSelector, limit);
365
+ if (jsonOutput) {
366
+ console.log(JSON.stringify(data.report, null, 2));
367
+ }
368
+ else {
369
+ renderTextReport(data);
370
+ }
371
+ return;
372
+ }
373
+ while (!stopRequested) {
374
+ const data = loadReport(db, automationId, runSelector, limit);
375
+ renderTextReport(data, true, watchIntervalMs);
376
+ await new Promise((resolve) => setTimeout(resolve, watchIntervalMs));
377
+ }
378
+ }
379
+ finally {
380
+ process.off('SIGINT', requestStop);
381
+ process.off('SIGTERM', requestStop);
382
+ cleanup();
383
+ }
384
+ }
385
+ await main();
@@ -0,0 +1,33 @@
1
+ import { getRegisteredAutomations as getRegisteredFromFile } from './registry.js';
2
+ import type { RunningAutomation } from './types.js';
3
+ export interface RuntimeOptions {
4
+ scriptPath: string;
5
+ id?: string;
6
+ dryRun?: boolean;
7
+ verbose?: boolean;
8
+ pollIntervalMs?: number;
9
+ /** Gateway port for webhook delivery. Falls back to OPENCLAW_GATEWAY_PORT or 18789 */
10
+ gatewayPort?: number;
11
+ /** Hooks token for webhook auth. Falls back to OPENCLAW_HOOKS_TOKEN */
12
+ hooksToken?: string;
13
+ /** Pre-seed state before the factory function runs (e.g. from --set key=value) */
14
+ initialState?: Record<string, unknown>;
15
+ /**
16
+ * Enable WebSocket for real-time events (allMids, orderUpdates, userFills, userEvents).
17
+ * When enabled, REST polling interval is relaxed to a heartbeat (default 60s).
18
+ * Falls back gracefully to polling if WebSocket connection fails.
19
+ * @default true
20
+ */
21
+ useWebSocket?: boolean;
22
+ /**
23
+ * Best-effort host idle-sleep inhibition for the lifetime of the automation.
24
+ * Enabled by default for live runs and disabled by default for dry runs.
25
+ */
26
+ keepAwake?: boolean;
27
+ }
28
+ export declare function getRunningAutomations(): RunningAutomation[];
29
+ export declare function getAutomation(id: string): RunningAutomation | undefined;
30
+ /** Get all automations from file-based registry (cross-process visibility) */
31
+ export { getRegisteredFromFile as getRegisteredAutomations };
32
+ export declare function startAutomation(options: RuntimeOptions): Promise<RunningAutomation>;
33
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../scripts/auto/runtime.ts"],"names":[],"mappings":"AAeA,OAAO,EAA4C,wBAAwB,IAAI,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAG5H,OAAO,KAAK,EAYV,iBAAiB,EAClB,MAAM,YAAY,CAAC;AAoZpB,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sFAAsF;IACtF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uEAAuE;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAKD,wBAAgB,qBAAqB,IAAI,iBAAiB,EAAE,CAE3D;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAEvE;AAED,8EAA8E;AAC9E,OAAO,EAAE,qBAAqB,IAAI,wBAAwB,EAAE,CAAC;AAE7D,wBAAsB,eAAe,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAohBzF"}