@senpi/runtime 3.0.146 → 3.0.149

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 (88) hide show
  1. package/dist/cli/guide-commands.d.ts.map +1 -1
  2. package/dist/cli/guide-commands.js +55 -0
  3. package/dist/cli/guide-commands.js.map +1 -1
  4. package/dist/cli/quant-command.d.ts +128 -0
  5. package/dist/cli/quant-command.d.ts.map +1 -0
  6. package/dist/cli/quant-command.js +345 -0
  7. package/dist/cli/quant-command.js.map +1 -0
  8. package/dist/cli/senpi-commands.d.ts +11 -0
  9. package/dist/cli/senpi-commands.d.ts.map +1 -1
  10. package/dist/cli/senpi-commands.js +49 -4
  11. package/dist/cli/senpi-commands.js.map +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +40 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/quant/engine/quantdesk/__init__.py +19 -0
  16. package/dist/quant/engine/quantdesk/__main__.py +281 -0
  17. package/dist/quant/engine/quantdesk/_version.py +24 -0
  18. package/dist/quant/engine/quantdesk/benchmark.py +90 -0
  19. package/dist/quant/engine/quantdesk/book.py +197 -0
  20. package/dist/quant/engine/quantdesk/deep.py +197 -0
  21. package/dist/quant/engine/quantdesk/desk.py +878 -0
  22. package/dist/quant/engine/quantdesk/dsl.py +224 -0
  23. package/dist/quant/engine/quantdesk/followups.py +117 -0
  24. package/dist/quant/engine/quantdesk/hl_api.py +473 -0
  25. package/dist/quant/engine/quantdesk/market.py +290 -0
  26. package/dist/quant/engine/quantdesk/mcp_client.py +158 -0
  27. package/dist/quant/engine/quantdesk/metrics.py +409 -0
  28. package/dist/quant/engine/quantdesk/opportunities.py +88 -0
  29. package/dist/quant/engine/quantdesk/render.py +787 -0
  30. package/dist/quant/engine/quantdesk/roundtrips.py +124 -0
  31. package/dist/quant/engine/quantdesk/score.py +817 -0
  32. package/dist/quant/engine/quantdesk/senpi_history.py +160 -0
  33. package/dist/quant/engine/quantdesk/smart_money.py +354 -0
  34. package/dist/quant/engine/quantdesk/strategy_read.py +292 -0
  35. package/dist/quant/engine/quantdesk/taxonomy.py +55 -0
  36. package/dist/quant/engine/quantdesk/timing.py +164 -0
  37. package/dist/quant/engine/quantdesk/voice.py +42 -0
  38. package/dist/quant/engine-runner.d.ts +133 -0
  39. package/dist/quant/engine-runner.d.ts.map +1 -0
  40. package/dist/quant/engine-runner.js +306 -0
  41. package/dist/quant/engine-runner.js.map +1 -0
  42. package/dist/quant/job.d.ts +125 -0
  43. package/dist/quant/job.d.ts.map +1 -0
  44. package/dist/quant/job.js +184 -0
  45. package/dist/quant/job.js.map +1 -0
  46. package/dist/quant/register.d.ts +53 -0
  47. package/dist/quant/register.d.ts.map +1 -0
  48. package/dist/quant/register.js +253 -0
  49. package/dist/quant/register.js.map +1 -0
  50. package/dist/quant/registry.d.ts +105 -0
  51. package/dist/quant/registry.d.ts.map +1 -0
  52. package/dist/quant/registry.js +248 -0
  53. package/dist/quant/registry.js.map +1 -0
  54. package/dist/quant/types.d.ts +216 -0
  55. package/dist/quant/types.d.ts.map +1 -0
  56. package/dist/quant/types.js +121 -0
  57. package/dist/quant/types.js.map +1 -0
  58. package/dist/skills-manager/manifest.js +1 -1
  59. package/dist/skills-manager/skills-manifest.json +73 -16
  60. package/dist/widgets/index.d.ts +8 -1
  61. package/dist/widgets/index.d.ts.map +1 -1
  62. package/dist/widgets/index.js +1 -0
  63. package/dist/widgets/index.js.map +1 -1
  64. package/dist/widgets/registry.d.ts +8 -0
  65. package/dist/widgets/registry.d.ts.map +1 -1
  66. package/dist/widgets/registry.js +26 -1
  67. package/dist/widgets/registry.js.map +1 -1
  68. package/dist/widgets/tool.d.ts +14 -4
  69. package/dist/widgets/tool.d.ts.map +1 -1
  70. package/dist/widgets/tool.js +36 -23
  71. package/dist/widgets/tool.js.map +1 -1
  72. package/dist/widgets/turn-cap.d.ts +33 -0
  73. package/dist/widgets/turn-cap.d.ts.map +1 -0
  74. package/dist/widgets/turn-cap.js +119 -0
  75. package/dist/widgets/turn-cap.js.map +1 -0
  76. package/dist/widgets/types.d.ts +33 -5
  77. package/dist/widgets/types.d.ts.map +1 -1
  78. package/dist/widgets/types.js +4 -3
  79. package/dist/widgets/types.js.map +1 -1
  80. package/dist/widgets/widgets/fund-user-wallet.d.ts.map +1 -1
  81. package/dist/widgets/widgets/fund-user-wallet.js +1 -0
  82. package/dist/widgets/widgets/fund-user-wallet.js.map +1 -1
  83. package/dist/widgets/widgets/quant-desk-recommendations.d.ts +52 -0
  84. package/dist/widgets/widgets/quant-desk-recommendations.d.ts.map +1 -0
  85. package/dist/widgets/widgets/quant-desk-recommendations.js +278 -0
  86. package/dist/widgets/widgets/quant-desk-recommendations.js.map +1 -0
  87. package/openclaw.plugin.json +12 -2
  88. package/package.json +4 -3
@@ -1 +1 @@
1
- {"version":3,"file":"guide-commands.d.ts","sourceRoot":"","sources":["../../src/cli/guide-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA4dH,eAAO,MAAM,eAAe,QAgWpB,CAAC;AAIT,kFAAkF;AAClF,UAAU,gBAAgB;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACvD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC9D,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC;CACxF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,MAAM,GACd,IAAI,CA2CN"}
1
+ {"version":3,"file":"guide-commands.d.ts","sourceRoot":"","sources":["../../src/cli/guide-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAsgBH,eAAO,MAAM,eAAe,QA0WpB,CAAC;AAIT,kFAAkF;AAClF,UAAU,gBAAgB;IACxB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IACvD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,gBAAgB,CAAC;IAC9D,MAAM,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,gBAAgB,CAAC;CACxF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,OAAO,EAAE,MAAM,GACd,IAAI,CAiDN"}
@@ -9,6 +9,7 @@
9
9
  * ScannerEngine exposes configSchema per scanner type. Relevant type is
10
10
  * ScannerRegistrationSummary in src/scanners/engine/engine.ts.
11
11
  */
12
+ import { QUANT_SECTIONS } from "../quant/types.js";
12
13
  const CHANGELOG_URL = "https://github.com/Senpi-ai/senpi-trading-runtime/blob/main/CHANGELOG.md";
13
14
  // ── Reference text constants ────────────────────────────────────────────────
14
15
  const OVERVIEW_TEXT = (version) => `
@@ -26,6 +27,8 @@ Quick commands:
26
27
  senpi validate <pkg> Prove a strategy runs before funding it (static → import → live)
27
28
  senpi deploy -p <pkg> Take a proven package live: create+fund → install → observe it running
28
29
  senpi update <pkg> Change a LIVE strategy's recipe in place — plans by default, --apply commits
30
+ senpi quant run <addr> The quant desk on any Hyperliquid wallet — score, leaks, next steps (read-only)
31
+ senpi guide quant Quant desk verbs, run ids, exit and refusal codes
29
32
  senpi scanner Per-scanner health: runs, errors, liveness, "(no signals yet)" flag
30
33
  senpi events Local domain-event log — the trade narrative
31
34
  senpi explain <asset> Stitch one asset's position lifecycle from the event log
@@ -474,6 +477,43 @@ exit:
474
477
  tiers:
475
478
  - { trigger_pct: 1, lock_hw_pct: 50 }
476
479
  `.trim();
480
+ /**
481
+ * `senpi guide quant` — the quant desk's verbs, the run-id line, exit and refusal codes.
482
+ *
483
+ * The quant-desk skill teaches the model these exact spellings, so this text is the in-shell copy
484
+ * of that contract: `[quant-desk] run <runId>` (the first stderr line of every started run), the
485
+ * exit classes, and which modes are refused `[E_QUANT_UNSUPPORTED]` in this release.
486
+ */
487
+ const QUANT_TEXT = `
488
+ senpi quant — the quant desk on any Hyperliquid wallet (read-only; it never trades)
489
+ ─────────────────────────────────────────────────────────────────────────────
490
+ openclaw senpi quant run <0x address> full desk as Markdown (waits; 30–180 s)
491
+ openclaw senpi quant run <0x a> <0x b> --book ONE desk over up to 25 wallets (a senpi user's strategy wallets)
492
+ openclaw senpi quant run <0x address> --other someone else's book, analyst voice
493
+ openclaw senpi quant run <0x address> --section overview --section leaks
494
+ openclaw senpi quant run <0x address> --json the desk document (doc_version 1) on stdout
495
+ openclaw senpi quant run <0x address> [--days N] [--mine|--other] [--no-wait]
496
+ openclaw senpi quant status [runId] newest run when no id
497
+ openclaw senpi quant show <runId> [--section <name>…] [--json] re-render a finished run, no recompute
498
+ openclaw senpi quant list the last 20 runs, newest first
499
+
500
+ The first stderr line is "[quant-desk] run <runId>" (match the line by its \`[quant-desk] run \`
501
+ prefix) — keep the id: 'show' re-renders any section from it, and show_widget's
502
+ quant_desk_recommendations card takes it as run_id.
503
+
504
+ Sections: ${QUANT_SECTIONS.join(", ")}
505
+ One desk per wallet set at a time: a second run is refused [E_QUANT_IN_PROGRESS] naming the running
506
+ id — poll 'quant status <id>', never start another. A finished desk for the same wallets, days and
507
+ voice is served for 10 minutes (--fresh recomputes). A run is stopped after 240 s.
508
+
509
+ Exit codes: 0 done · 2 refused (obey the [E_QUANT_*] message; do not retry) · 3 failed (the message
510
+ says what to do) · 6 still running, or its state is unknown after the run line — poll
511
+ 'quant status <id>' · 1 transport/internal, only before a run id exists (nothing started).
512
+ Refusals: E_QUANT_INVALID_REQUEST · E_QUANT_UNSUPPORTED (--deep, --find, --compare are not available
513
+ through the runtime yet) · E_QUANT_IN_PROGRESS · E_QUANT_NO_ACTIVITY · E_QUANT_NOT_A_TRADER (a vault,
514
+ or a book wider than the desk reads; --force only if the reader insists) · E_QUANT_NOT_FOUND ·
515
+ E_QUANT_DOC_VERSION. Failures: E_QUANT_UPSTREAM · E_QUANT_TIMEOUT · E_QUANT_ENGINE_ERROR.
516
+ `.trim();
477
517
  export const CHEATSHEET_TEXT = `
478
518
  Senpi Plugin Commands Cheatsheet
479
519
  ================================
@@ -560,6 +600,15 @@ senpi deploy — Take a strategy package live, end to end (the strategy lifecycl
560
600
  $0.00 — ask the USER to verify what actually landed before
561
601
  any money action
562
602
 
603
+ senpi quant — The quant desk on any Hyperliquid wallet (read-only)
604
+ quant run <address…> Run and print the desk (waits). Prints "[quant-desk] run <id>" first
605
+ --days <n> · --other | --mine · --book · --fresh · --force · --section <name> (repeatable) · --json · --no-wait
606
+ quant status [runId] Status of a run (newest when omitted)
607
+ quant show <runId> Re-render a finished run (--section, --json); never recomputes
608
+ quant list Last 20 runs
609
+ Exit codes: 0 done · 2 refused · 3 failed · 6 running or state unknown · 1 error before a run exists.
610
+ See: senpi guide quant
611
+
563
612
  senpi runtime — Manage runtimes
564
613
  runtime delete [id] Remove a runtime
565
614
  --id <runtime_id> Delete by runtime ID
@@ -758,6 +807,7 @@ senpi guide — In-shell reference
758
807
  guide examples Print minimal strategy YAML
759
808
  guide schema Full YAML schema field reference
760
809
  guide version Plugin version and changelog URL
810
+ guide quant Quant desk verbs and codes
761
811
 
762
812
  Gateway Methods
763
813
  ---------------
@@ -853,6 +903,11 @@ export function registerGuideCommands(senpi, version) {
853
903
  .action(() => {
854
904
  process.stdout.write(DSL_TEXT + "\n");
855
905
  });
906
+ guide.command("quant")
907
+ .description("Quant desk: run, status, show, list; run ids; exit and refusal codes")
908
+ .action(() => {
909
+ process.stdout.write(QUANT_TEXT + "\n");
910
+ });
856
911
  guide.command("examples")
857
912
  .description("Print minimal strategy YAML to stdout")
858
913
  .action(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"guide-commands.js","sourceRoot":"","sources":["../../src/cli/guide-commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"guide-commands.js","sourceRoot":"","sources":["../../src/cli/guide-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * The slice of Commander this module registers against. Declared locally (like the other verb
3
+ * modules) so the file does not depend on OpenClaw's Commander instance type.
4
+ */
5
+ interface CommanderCommand {
6
+ command(name: string): CommanderCommand;
7
+ description(text: string): CommanderCommand;
8
+ option(flags: string, description: string, parseArg?: unknown, defaultValue?: unknown): CommanderCommand;
9
+ argument(name: string, description: string): CommanderCommand;
10
+ action(handler: (...args: never[]) => void | Promise<void>): CommanderCommand;
11
+ }
12
+ /**
13
+ * Exit codes, fixed so a caller can branch once. Same classes as `deploy status`: 2 means obey the
14
+ * refusal (never retry it), 6 means poll `quant status`, 1 means the run's state is unknown.
15
+ */
16
+ export declare const QUANT_EXIT: {
17
+ readonly ok: 0;
18
+ readonly error: 1;
19
+ readonly refused: 2;
20
+ readonly failed: 3;
21
+ readonly running: 6;
22
+ };
23
+ /** Poll interval while a run is in flight. */
24
+ export declare const QUANT_POLL_MS = 2000;
25
+ /** Per-call timeout for status polls (the `gateway call` default is 10 s, too tight under load). */
26
+ export declare const QUANT_STATUS_TIMEOUT_MS = 15000;
27
+ /** Per-call timeout for `get` (a Markdown re-render spawns Python). */
28
+ export declare const QUANT_GET_TIMEOUT_MS = 30000;
29
+ /**
30
+ * How long `run` waits before handing the reader the status command: the engine's 240 s cap plus
31
+ * slack. Deliberately BELOW the quant-desk skill's 300 s exec timeout, so the CLI's own exit-6
32
+ * message (with the status command) is what the reader sees — at 300 s the two tied and the exec
33
+ * harness could kill the CLI before it spoke.
34
+ */
35
+ export declare const QUANT_WAIT_CAP_MS = 270000;
36
+ /**
37
+ * Consecutive empty status-poll replies tolerated once a run id exists. One transport timeout or
38
+ * null reply mid-poll used to end the wait with exit 1, which the skill reads as "the desk did not
39
+ * run" — while the gateway job kept running. Two are re-polled; the third ends the wait with exit 6
40
+ * and the status command, because the run's state is unknown, not failed.
41
+ */
42
+ export declare const QUANT_EMPTY_POLLS_TOLERATED = 2;
43
+ /**
44
+ * What `callGatewayJson` hands back: the gateway's answer. `undefined` means the transport already
45
+ * reported the problem AND set the exit code (a refusal → 2, a transport failure → 1), so callers
46
+ * return without printing or touching the exit code.
47
+ */
48
+ export type GatewayReply = {
49
+ ok?: boolean;
50
+ payload?: unknown;
51
+ error?: unknown;
52
+ };
53
+ /**
54
+ * The command's I/O, injected so routing and exit codes are testable without a CLI or a gateway.
55
+ * Production wiring lives in `registerSenpiCli` (`senpi-commands.ts`).
56
+ */
57
+ export interface QuantCommandDeps {
58
+ /** One `openclaw gateway call`; `opts.timeoutMs` becomes `--timeout`. */
59
+ callGateway(method: string, params: Record<string, unknown>, opts?: {
60
+ timeoutMs?: number;
61
+ }): GatewayReply | undefined;
62
+ /** stdout — the desk, the document, or a status/list rendering. Must survive OpenClaw's --json diversion. */
63
+ out(text: string): void;
64
+ /** stderr — the run line, progress, refusals, next steps. */
65
+ err(line: string): void;
66
+ /** Sets `process.exitCode` in production. */
67
+ setExitCode(code: number): void;
68
+ /** Wait between polls. */
69
+ sleep(ms: number): Promise<void>;
70
+ /** Clock for the wait cap. */
71
+ now(): number;
72
+ }
73
+ /** `run` flags as Commander delivers them (`--no-wait` → `wait: false`). */
74
+ export interface QuantRunFlags {
75
+ days?: string;
76
+ other?: boolean;
77
+ mine?: boolean;
78
+ book?: boolean;
79
+ fresh?: boolean;
80
+ force?: boolean;
81
+ section?: readonly string[];
82
+ json?: boolean;
83
+ wait?: boolean;
84
+ /**
85
+ * Declared only so it can be refused `[E_QUANT_UNSUPPORTED]` instead of Commander's generic error.
86
+ * The value is optional (`--deep [mode]`), so a bare `--deep` arrives as `true`.
87
+ */
88
+ deep?: string | boolean;
89
+ /** Declared only so it can be refused `[E_QUANT_UNSUPPORTED]`; bare `--find` arrives as `true`. */
90
+ find?: string | boolean;
91
+ /** Declared only so it can be refused `[E_QUANT_UNSUPPORTED]`. */
92
+ compare?: boolean;
93
+ }
94
+ /** `show` flags (`status` and `list` take only `json`). */
95
+ export interface QuantReadFlags {
96
+ section?: readonly string[];
97
+ json?: boolean;
98
+ }
99
+ /**
100
+ * `senpi quant run <address…>`: validate locally, start the gateway job, print the run line, then
101
+ * (unless `--no-wait`) poll until settled and print the desk.
102
+ *
103
+ * Local refusals (unsupported mode, contradictory voice, no address, unknown section, bad days)
104
+ * happen before any gateway call. Address shape, book width and day bounds are the gateway's to
105
+ * judge — the CLI does not duplicate them.
106
+ */
107
+ export declare function runQuantRun(deps: QuantCommandDeps, addresses: string[], flags: QuantRunFlags): Promise<void>;
108
+ /** `senpi quant status [runId]` — no id = the newest run. Exit code follows the run's status. */
109
+ export declare function runQuantStatus(deps: QuantCommandDeps, runId: string | undefined, flags: {
110
+ json?: boolean;
111
+ }): Promise<void>;
112
+ /** `senpi quant show <runId>` — re-render from the stored document, never recompute. */
113
+ export declare function runQuantShow(deps: QuantCommandDeps, runId: string, flags: QuantReadFlags): Promise<void>;
114
+ /**
115
+ * `senpi quant list` — the stored runs, newest first (normally the last 20; more while runs are in
116
+ * flight). One line per run: id, status, window, whose (+ "book"), wallets, finished-or-started.
117
+ */
118
+ export declare function runQuantList(deps: QuantCommandDeps, flags: {
119
+ json?: boolean;
120
+ }): Promise<void>;
121
+ /**
122
+ * Register `senpi quant run|status|show|list`. `--deep/--find/--compare` are declared so they reach
123
+ * `runQuantRun` and are refused with `[E_QUANT_UNSUPPORTED]` naming what is supported, rather than
124
+ * dying on Commander's generic "unknown option".
125
+ */
126
+ export declare function registerQuantCommands(senpi: CommanderCommand, deps: QuantCommandDeps): void;
127
+ export {};
128
+ //# sourceMappingURL=quant-command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quant-command.d.ts","sourceRoot":"","sources":["../../src/cli/quant-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,345 @@
1
+ /**
2
+ * `openclaw senpi quant` — run | status | show | list.
3
+ *
4
+ * Thin, like `senpi update`: parse flags, call the gateway, render, set the exit code. No engine
5
+ * logic lives here — every verb is one or more `senpi.quant.*` gateway calls (see
6
+ * `src/quant/register.ts`), so the CLI can never disagree with what the gateway stored.
7
+ *
8
+ * `run` starts a gateway job and polls it (a desk takes 30–180 s and `gateway call` times out at
9
+ * 10 s by default), so the model's experience stays one command. Once the gateway has started (or
10
+ * served) a run, the FIRST stderr line is always `[quant-desk] run <id>` — in every mode, including
11
+ * `--section`, `--json`, `--no-wait` and a cached run (which adds a parenthesised suffix after the
12
+ * id). That line is a contract: the quant-desk skill prefix-matches `[quant-desk] run ` and reads
13
+ * the id as the next word, then hands it to `show` and to the recommendation card. A run refused
14
+ * before it starts (bad flags, bad address, `[E_QUANT_IN_PROGRESS]`) has no id, so its first
15
+ * stderr line is the bracketed refusal instead.
16
+ *
17
+ * Exit codes: 0 done · 2 refused (obey the [E_QUANT_*] message) · 3 failed · 6 still running, or its
18
+ * state is unknown after the run line (poll `quant status <id>`) · 1 transport/internal, only before
19
+ * a run id exists. --json output is exactly one document on stdout.
20
+ */
21
+ import { isRefusalMessage } from "../deploy/taxonomy.js";
22
+ import { QUANT_SECTIONS } from "../quant/types.js";
23
+ /**
24
+ * Exit codes, fixed so a caller can branch once. Same classes as `deploy status`: 2 means obey the
25
+ * refusal (never retry it), 6 means poll `quant status`, 1 means the run's state is unknown.
26
+ */
27
+ export const QUANT_EXIT = { ok: 0, error: 1, refused: 2, failed: 3, running: 6 };
28
+ /** Poll interval while a run is in flight. */
29
+ export const QUANT_POLL_MS = 2_000;
30
+ /** Per-call timeout for status polls (the `gateway call` default is 10 s, too tight under load). */
31
+ export const QUANT_STATUS_TIMEOUT_MS = 15_000;
32
+ /** Per-call timeout for `get` (a Markdown re-render spawns Python). */
33
+ export const QUANT_GET_TIMEOUT_MS = 30_000;
34
+ /**
35
+ * How long `run` waits before handing the reader the status command: the engine's 240 s cap plus
36
+ * slack. Deliberately BELOW the quant-desk skill's 300 s exec timeout, so the CLI's own exit-6
37
+ * message (with the status command) is what the reader sees — at 300 s the two tied and the exec
38
+ * harness could kill the CLI before it spoke.
39
+ */
40
+ export const QUANT_WAIT_CAP_MS = 270_000;
41
+ /**
42
+ * Consecutive empty status-poll replies tolerated once a run id exists. One transport timeout or
43
+ * null reply mid-poll used to end the wait with exit 1, which the skill reads as "the desk did not
44
+ * run" — while the gateway job kept running. Two are re-polled; the third ends the wait with exit 6
45
+ * and the status command, because the run's state is unknown, not failed.
46
+ */
47
+ export const QUANT_EMPTY_POLLS_TOLERATED = 2;
48
+ /** Every supported spelling, quoted by the usage and `[E_QUANT_UNSUPPORTED]` refusals. */
49
+ const SUPPORTED = "openclaw senpi quant run <address…> [--days N] [--other|--mine] [--book] [--fresh] [--force] [--section <name>…] [--json] [--no-wait] · " +
50
+ "quant status [runId] · quant show <runId> [--section <name>…] [--json] · quant list";
51
+ /** `gateway call --json` prints the payload itself; tolerate a wrapped `{ok, payload}` too. */
52
+ function payloadOf(reply) {
53
+ return (reply.payload ?? reply);
54
+ }
55
+ /** Map a run's status onto the exit-code classes. */
56
+ function exitFor(status) {
57
+ return status === "done" ? QUANT_EXIT.ok : status === "running" ? QUANT_EXIT.running : status === "refused" ? QUANT_EXIT.refused : QUANT_EXIT.failed;
58
+ }
59
+ /** A refusal decided before any gateway call: one bracketed line, exit 2, nothing started. */
60
+ function refuseLocally(deps, message) {
61
+ deps.err(message);
62
+ deps.setExitCode(QUANT_EXIT.refused);
63
+ }
64
+ /**
65
+ * A gateway `ok:false` that reached us as a value: bracketed code → refused (2); anything else →
66
+ * internal (1). The message is printed verbatim — re-run hints in it already carry the request's
67
+ * `--book/--other/--days`, so the CLI never rebuilds them.
68
+ */
69
+ function reportGatewayError(deps, reply) {
70
+ const message = (reply.error ?? {}).message ?? "The gateway refused the request.";
71
+ deps.err(message);
72
+ deps.setExitCode(isRefusalMessage(message) ? QUANT_EXIT.refused : QUANT_EXIT.error);
73
+ }
74
+ /** Print a refused/failed run's message and, when it has one, its next step. Exit code is the caller's. */
75
+ function reportRunError(deps, s) {
76
+ if (!s.error)
77
+ return;
78
+ deps.err(s.error.message);
79
+ if (s.error.what_to_do)
80
+ deps.err(`Next: ${s.error.what_to_do}`);
81
+ }
82
+ /**
83
+ * Validate `--section` names against the engine's `QUANT_SECTIONS`. Returns `undefined` (after
84
+ * refusing locally) on an unknown name, so a typo never starts a 3-minute run.
85
+ */
86
+ function parseSections(deps, raw) {
87
+ const known = QUANT_SECTIONS;
88
+ const unknown = (raw ?? []).filter((s) => !known.includes(s));
89
+ if (unknown.length > 0) {
90
+ refuseLocally(deps, `[E_QUANT_INVALID_REQUEST] unknown section: ${unknown.join(", ")}. Sections: ${QUANT_SECTIONS.join(", ")}.`);
91
+ return undefined;
92
+ }
93
+ return (raw ?? []);
94
+ }
95
+ /**
96
+ * Fetch and print a finished run (Markdown, or the JSON document with `json`) from the stored
97
+ * record; never recomputes. A run that is not `done` reports its status and exits by it.
98
+ *
99
+ * @returns `"shown"` only when the desk (or document) was printed — callers gate follow-up hints on
100
+ * it, so a refused or failed `get` is never followed by "done — show it again". `"no-reply"` means
101
+ * the transport returned nothing (it already printed its text and set the exit code), so a caller
102
+ * that knows the run exists can re-classify it; `"reported"` means the outcome is fully reported.
103
+ */
104
+ async function showRun(deps, runId, sections, json) {
105
+ const reply = deps.callGateway("senpi.quant.get", { runId, format: json ? "json" : "markdown", ...(sections.length > 0 ? { sections } : {}) }, { timeoutMs: QUANT_GET_TIMEOUT_MS });
106
+ if (!reply)
107
+ return "no-reply";
108
+ if (reply.ok === false) {
109
+ reportGatewayError(deps, reply);
110
+ return "reported";
111
+ }
112
+ const got = payloadOf(reply);
113
+ if (got.status !== "done") {
114
+ if (json)
115
+ deps.out(JSON.stringify(got, null, 2));
116
+ if (got.status === "running")
117
+ deps.err(`[quant-desk] run ${runId} is still running; poll it: openclaw senpi quant status ${runId}`);
118
+ reportRunError(deps, got);
119
+ deps.setExitCode(exitFor(got.status));
120
+ return "reported";
121
+ }
122
+ deps.out(json ? JSON.stringify(got.document ?? null, null, 2) : got.markdown ?? "");
123
+ deps.setExitCode(QUANT_EXIT.ok);
124
+ return "shown";
125
+ }
126
+ /**
127
+ * The run exists but its state could not be read: print `line` (which names the command to run
128
+ * next) and exit 6. Used wherever a
129
+ * reply went missing AFTER the run line was printed — exit 1 there would read as "the desk did not
130
+ * run" while the gateway job may well still be running (or already done).
131
+ */
132
+ function reportStateUnknown(deps, line) {
133
+ deps.err(line);
134
+ deps.setExitCode(QUANT_EXIT.running);
135
+ }
136
+ /**
137
+ * Poll `senpi.quant.status` every `QUANT_POLL_MS` until the run leaves `running`, relaying each NEW
138
+ * progress line once to stderr. Returns the settled status, or `undefined` when this function has
139
+ * already reported the outcome (a bracketed gateway refusal → 2, the wait cap or
140
+ * `QUANT_EMPTY_POLLS_TOLERATED` + 1 consecutive empty replies → 6 with the status command). The wait
141
+ * cap is checked on every poll, empty or not, so no mix of empty and answered replies can stretch
142
+ * the wait past `QUANT_WAIT_CAP_MS` (plus the one poll in flight). The run itself is a gateway job,
143
+ * so giving up waiting never stops it.
144
+ *
145
+ * An "empty" reply is a null from the transport (timeout, dispatch failure — the transport has
146
+ * already printed its text and set exit 1, which a later answer overwrites) or an uncoded
147
+ * `ok:false`. A bracketed `ok:false` is an answer and is obeyed at once. A null that was in fact a
148
+ * gateway refusal (the transport cannot tell us) is re-polled too; after the third it reads exit 6,
149
+ * and the status command it names then prints the refusal with its own exit 2.
150
+ */
151
+ async function pollUntilSettled(deps, runId) {
152
+ const deadline = deps.now() + QUANT_WAIT_CAP_MS;
153
+ let lastProgress;
154
+ let empty = 0;
155
+ for (;;) {
156
+ await deps.sleep(QUANT_POLL_MS);
157
+ const reply = deps.callGateway("senpi.quant.status", { runId }, { timeoutMs: QUANT_STATUS_TIMEOUT_MS });
158
+ if (reply?.ok === false && isRefusalMessage((reply.error ?? {}).message ?? "")) {
159
+ reportGatewayError(deps, reply);
160
+ return undefined;
161
+ }
162
+ if (!reply || reply.ok === false) {
163
+ if (reply)
164
+ deps.err((reply.error ?? {}).message ?? "The gateway gave no answer.");
165
+ empty += 1;
166
+ // The cap binds here too: without it, empty replies around the deadline re-poll past 270 s.
167
+ if (empty > QUANT_EMPTY_POLLS_TOLERATED || deps.now() >= deadline) {
168
+ reportStateUnknown(deps, `[quant-desk] run ${runId}: state unknown; the desk may still be running — its state: openclaw senpi quant status ${runId}`);
169
+ return undefined;
170
+ }
171
+ continue;
172
+ }
173
+ empty = 0;
174
+ const st = payloadOf(reply);
175
+ if (st.progress && st.progress !== lastProgress) {
176
+ deps.err(st.progress);
177
+ lastProgress = st.progress;
178
+ }
179
+ if (st.status !== "running")
180
+ return st;
181
+ if (deps.now() >= deadline) {
182
+ deps.err(`[quant-desk] run ${runId} is still running after ${QUANT_WAIT_CAP_MS / 1000}s; poll it: openclaw senpi quant status ${runId}`);
183
+ deps.setExitCode(QUANT_EXIT.running);
184
+ return undefined;
185
+ }
186
+ }
187
+ }
188
+ /**
189
+ * `senpi quant run <address…>`: validate locally, start the gateway job, print the run line, then
190
+ * (unless `--no-wait`) poll until settled and print the desk.
191
+ *
192
+ * Local refusals (unsupported mode, contradictory voice, no address, unknown section, bad days)
193
+ * happen before any gateway call. Address shape, book width and day bounds are the gateway's to
194
+ * judge — the CLI does not duplicate them.
195
+ */
196
+ export async function runQuantRun(deps, addresses, flags) {
197
+ const unsupported = flags.deep !== undefined ? "--deep" : flags.find !== undefined ? "--find" : flags.compare ? "--compare" : undefined;
198
+ if (unsupported)
199
+ return refuseLocally(deps, `[E_QUANT_UNSUPPORTED] ${unsupported} is not available through the runtime yet. Supported: ${SUPPORTED}`);
200
+ if (flags.other && flags.mine)
201
+ return refuseLocally(deps, "[E_QUANT_INVALID_REQUEST] --other and --mine contradict each other; pass one. Nothing was started.");
202
+ if (addresses.length === 0)
203
+ return refuseLocally(deps, `[E_QUANT_INVALID_REQUEST] an address is required. Usage: ${SUPPORTED}`);
204
+ const sections = parseSections(deps, flags.section);
205
+ if (!sections)
206
+ return;
207
+ let days;
208
+ if (flags.days !== undefined) {
209
+ days = Number(flags.days);
210
+ if (!Number.isInteger(days))
211
+ return refuseLocally(deps, `[E_QUANT_INVALID_REQUEST] --days must be a whole number; got "${flags.days}". Nothing was started.`);
212
+ }
213
+ const started = deps.callGateway("senpi.quant.start", {
214
+ addresses,
215
+ ...(days !== undefined ? { days } : {}),
216
+ whose: flags.other ? "other" : "mine",
217
+ book: flags.book === true,
218
+ fresh: flags.fresh === true,
219
+ force: flags.force === true,
220
+ });
221
+ if (!started)
222
+ return;
223
+ if (started.ok === false)
224
+ return reportGatewayError(deps, started);
225
+ const s = payloadOf(started);
226
+ // The run line: first stderr line in every mode once a run exists (see the module JSDoc).
227
+ deps.err(`[quant-desk] run ${s.runId}${s.cached ? " (served from a run finished in the last 10 minutes; --fresh recomputes)" : ""}`);
228
+ if (flags.wait === false) {
229
+ deps.out(JSON.stringify({ runId: s.runId }));
230
+ deps.setExitCode(s.status === "done" ? QUANT_EXIT.ok : QUANT_EXIT.running);
231
+ return;
232
+ }
233
+ const final = s.status === "done" ? { runId: s.runId, status: "done" } : await pollUntilSettled(deps, s.runId);
234
+ if (!final)
235
+ return;
236
+ if (final.status !== "done") {
237
+ if (flags.json === true)
238
+ deps.out(JSON.stringify(final, null, 2));
239
+ reportRunError(deps, final);
240
+ deps.setExitCode(exitFor(final.status));
241
+ return;
242
+ }
243
+ const shown = await showRun(deps, s.runId, sections, flags.json === true);
244
+ if (shown === "no-reply") {
245
+ // The run finished; only the fetch of its desk went unanswered. Exit 1 would read as "the
246
+ // desk did not run" — exit 6 and the command that prints it instead.
247
+ reportStateUnknown(deps, `[quant-desk] run ${s.runId} finished but its desk could not be fetched — show it: openclaw senpi quant show ${s.runId}`);
248
+ return;
249
+ }
250
+ if (shown !== "shown")
251
+ return;
252
+ deps.err(`[quant-desk] run ${s.runId} done — any section again, without recomputing: openclaw senpi quant show ${s.runId} --section <name>`);
253
+ }
254
+ /** `senpi quant status [runId]` — no id = the newest run. Exit code follows the run's status. */
255
+ export async function runQuantStatus(deps, runId, flags) {
256
+ const reply = deps.callGateway("senpi.quant.status", runId ? { runId } : {}, { timeoutMs: QUANT_STATUS_TIMEOUT_MS });
257
+ if (!reply)
258
+ return;
259
+ if (reply.ok === false)
260
+ return reportGatewayError(deps, reply);
261
+ const st = payloadOf(reply);
262
+ deps.setExitCode(exitFor(st.status));
263
+ if (flags.json)
264
+ return deps.out(JSON.stringify(st, null, 2));
265
+ deps.out(`run ${st.runId} · ${st.status} · started ${st.startedAt ?? "?"}${st.finishedAt ? ` · finished ${st.finishedAt}` : ""}`);
266
+ if (st.progress)
267
+ deps.out(` ${st.progress}`);
268
+ if (st.status === "done")
269
+ deps.out(` read it: openclaw senpi quant show ${st.runId}`);
270
+ if (st.status === "running")
271
+ deps.out(` poll again in a few seconds: openclaw senpi quant status ${st.runId}`);
272
+ reportRunError(deps, st);
273
+ }
274
+ /** `senpi quant show <runId>` — re-render from the stored document, never recompute. */
275
+ export async function runQuantShow(deps, runId, flags) {
276
+ const sections = parseSections(deps, flags.section);
277
+ if (!sections)
278
+ return;
279
+ await showRun(deps, runId, sections, flags.json === true);
280
+ }
281
+ /**
282
+ * `senpi quant list` — the stored runs, newest first (normally the last 20; more while runs are in
283
+ * flight). One line per run: id, status, window, whose (+ "book"), wallets, finished-or-started.
284
+ */
285
+ export async function runQuantList(deps, flags) {
286
+ const reply = deps.callGateway("senpi.quant.list", {});
287
+ if (!reply)
288
+ return;
289
+ if (reply.ok === false)
290
+ return reportGatewayError(deps, reply);
291
+ const { runs } = payloadOf(reply);
292
+ deps.setExitCode(QUANT_EXIT.ok);
293
+ if (flags.json)
294
+ return deps.out(JSON.stringify({ runs }, null, 2));
295
+ if (runs.length === 0)
296
+ return deps.out("No quant runs yet. Start one: openclaw senpi quant run <0x address>");
297
+ for (const r of runs) {
298
+ deps.out(`${r.runId} ${r.status.padEnd(8)} ${r.days}d ${r.whose}${r.book ? " book" : ""} ${r.addresses.join(",")} ${r.finishedAt ?? r.startedAt}`);
299
+ }
300
+ }
301
+ /**
302
+ * Register `senpi quant run|status|show|list`. `--deep/--find/--compare` are declared so they reach
303
+ * `runQuantRun` and are refused with `[E_QUANT_UNSUPPORTED]` naming what is supported, rather than
304
+ * dying on Commander's generic "unknown option".
305
+ */
306
+ export function registerQuantCommands(senpi, deps) {
307
+ const collect = (value, prev = []) => [...prev, value];
308
+ const quant = senpi.command("quant").description("The quant desk on any Hyperliquid wallet — score, leaks, next steps (read-only). Exit codes: 0 done · 2 refused · 3 failed · 6 still running or state unknown (poll quant status) · 1 error before a run exists");
309
+ quant.command("run")
310
+ .description("Run the desk and print it (waits; 30–180 s). First stderr line: [quant-desk] run <runId>")
311
+ // Optional to Commander on purpose: a missing address must reach runQuantRun and be refused
312
+ // [E_QUANT_INVALID_REQUEST] (exit 2), not die on Commander's own un-coded error (exit 1).
313
+ .argument("[address...]", "One wallet, or several with --book (required)")
314
+ .option("--days <n>", "Window in days (default 90)")
315
+ .option("--other", "Someone else's book (analyst voice)")
316
+ .option("--mine", "The reader's own book (default)")
317
+ .option("--book", "Read several wallets as ONE book (a senpi user's strategy wallets)")
318
+ .option("--fresh", "Recompute even if the same desk finished in the last 10 minutes")
319
+ .option("--force", "Read a vault or a very wide book anyway (only when the reader insists)")
320
+ .option("--section <name>", `Print only these sections (repeatable): ${QUANT_SECTIONS.join(", ")}`, collect)
321
+ .option("--json", "Print the desk document (doc_version 1) as JSON on stdout")
322
+ .option("--no-wait", "Start and print {runId} without waiting (exit 6 while running)")
323
+ // Optional values: a bare trailing `--deep`/`--find` must still reach [E_QUANT_UNSUPPORTED]
324
+ // rather than die on Commander's un-coded "argument missing" (exit 1).
325
+ .option("--deep [mode]", "Not available through the runtime yet (refused)")
326
+ .option("--find [band]", "Not available through the runtime yet (refused)")
327
+ .option("--compare", "Not available through the runtime yet (refused)")
328
+ .action(async (addresses, flags) => runQuantRun(deps, addresses ?? [], flags));
329
+ quant.command("status")
330
+ .description("A run's status; the newest when no id is given")
331
+ .argument("[runId]", "Run id from `[quant-desk] run <id>`")
332
+ .option("--json", "Raw JSON")
333
+ .action(async (runId, flags) => runQuantStatus(deps, runId, flags));
334
+ quant.command("show")
335
+ .description("Re-render a finished run from the stored document (never recomputes)")
336
+ .argument("<runId>", "Run id")
337
+ .option("--section <name>", "Only these sections (repeatable)", collect)
338
+ .option("--json", "The stored document as JSON")
339
+ .action(async (runId, flags) => runQuantShow(deps, runId, flags));
340
+ quant.command("list")
341
+ .description("The last 20 runs, newest first")
342
+ .option("--json", "Raw JSON")
343
+ .action(async (flags) => runQuantList(deps, flags));
344
+ }
345
+ //# sourceMappingURL=quant-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quant-command.js","sourceRoot":"","sources":["../../src/cli/quant-command.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,17 @@ import type { StoredEvent } from "../telemetry/event-store.js";
10
10
  export declare function registerSenpiCli(program: {
11
11
  command: (name: string, desc?: string) => CommanderCommand | unknown;
12
12
  }): void;
13
+ /**
14
+ * argv for `openclaw gateway call`. Exported so the timeout wiring is testable without a
15
+ * subprocess. `--timeout` is the per-call gateway timeout (the CLI default is 10 s); omitting
16
+ * `timeoutMs` keeps the historical argv byte-for-byte, so every existing caller is unchanged.
17
+ *
18
+ * @param method Gateway method name, e.g. `senpi.quant.status`.
19
+ * @param params JSON-serialisable params, passed as one `--params` argv element (never via a shell).
20
+ * @param timeoutMs Optional per-call timeout in milliseconds, placed before `--params`.
21
+ * @returns argv to append after the OpenClaw entry script.
22
+ */
23
+ export declare function gatewayCallArgs(method: string, params: Record<string, unknown>, timeoutMs?: number): string[];
13
24
  /**
14
25
  * Render the risk audit log as a tab-separated digest (newest entries last,
15
26
  * as returned). Each row: time, source, then `guardrail=result` per