@leroylabs/cli 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +20 -0
- package/README.md +17 -9
- package/package.json +4 -2
- package/src/format.mjs +68 -29
- package/src/live-ui.mjs +20 -14
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Leroy Labs CLI Proprietary License
|
|
2
|
+
|
|
3
|
+
Copyright © 2026 Leroy Labs. All rights reserved.
|
|
4
|
+
|
|
5
|
+
Leroy Labs grants you a limited, revocable, non-exclusive,
|
|
6
|
+
non-transferable, non-sublicensable license to install and use an unmodified
|
|
7
|
+
copy of this package solely to access the Leroy service in accordance with the
|
|
8
|
+
Leroy Terms at https://getleroy.com/legal.
|
|
9
|
+
|
|
10
|
+
Except for that limited license, Leroy Labs retains all right, title, and
|
|
11
|
+
interest in and to this package, including its source code, interfaces,
|
|
12
|
+
documentation, trademarks, and related intellectual property. You may not
|
|
13
|
+
copy, modify, create derivative works from, distribute, publish, sublicense,
|
|
14
|
+
sell, lease, reverse engineer, decompile, disassemble, or otherwise make this
|
|
15
|
+
package or its source code available to any third party, except to the extent
|
|
16
|
+
such restriction is prohibited by applicable law.
|
|
17
|
+
|
|
18
|
+
This package may include third-party components governed by their respective
|
|
19
|
+
license terms. Nothing in this license grants rights to Leroy Labs trademarks
|
|
20
|
+
or branding.
|
package/README.md
CHANGED
|
@@ -55,23 +55,31 @@ which matches the one-minute tape cadence; use `--interval SECONDS` to choose a
|
|
|
55
55
|
different polling interval. Each refresh is an authenticated evaluation request
|
|
56
56
|
and may count toward the account's lookup allowance.
|
|
57
57
|
|
|
58
|
-
##
|
|
58
|
+
## Evidence Strength
|
|
59
59
|
|
|
60
60
|
Leroy selects the strongest available evidence tier and does not pool lower
|
|
61
61
|
tiers into it:
|
|
62
62
|
|
|
63
|
-
- `5/5`:
|
|
64
|
-
- `4/5`:
|
|
65
|
-
- `3/5`:
|
|
66
|
-
- `2/5`:
|
|
67
|
-
- `1/5`:
|
|
63
|
+
- `5/5`: Exact Setup
|
|
64
|
+
- `4/5`: Cross-Ticker Setup
|
|
65
|
+
- `3/5`: Signal Pattern
|
|
66
|
+
- `2/5`: Contextual Analogue
|
|
67
|
+
- `1/5`: Direction-Only Baseline
|
|
68
|
+
- `0/5`: No Comparable Evidence
|
|
68
69
|
|
|
69
|
-
The human-readable output shows
|
|
70
|
-
|
|
71
|
-
basis, or `--json` for the complete
|
|
70
|
+
The human-readable output shows a scope-specific observation count according to
|
|
71
|
+
the selected tier; these are observations in that evidence scope, not setup
|
|
72
|
+
matches. Use `--verbose` for the full match basis, or `--json` for the complete
|
|
73
|
+
structured response.
|
|
72
74
|
|
|
73
75
|
The browser reference is available at [getleroy.com/cli](https://getleroy.com/cli).
|
|
74
76
|
|
|
77
|
+
## License
|
|
78
|
+
|
|
79
|
+
Copyright © 2026 Leroy Labs. This package is proprietary software, licensed
|
|
80
|
+
only for use with Leroy under the [Leroy Terms](https://getleroy.com/legal).
|
|
81
|
+
See [LICENSE](./LICENSE) for the package license.
|
|
82
|
+
|
|
75
83
|
## Exit codes
|
|
76
84
|
|
|
77
85
|
- `0`: the request completed and returned a valid Leroy response. This includes
|
package/package.json
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leroylabs/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Command-line access to Leroy market evidence.",
|
|
5
5
|
"homepage": "https://getleroy.com",
|
|
6
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
6
7
|
"type": "module",
|
|
7
8
|
"files": [
|
|
8
9
|
"bin",
|
|
9
10
|
"src",
|
|
10
|
-
"README.md"
|
|
11
|
+
"README.md",
|
|
12
|
+
"LICENSE"
|
|
11
13
|
],
|
|
12
14
|
"publishConfig": {
|
|
13
15
|
"access": "public"
|
package/src/format.mjs
CHANGED
|
@@ -131,7 +131,8 @@ function memoryMatchCounts(response) {
|
|
|
131
131
|
const rowCount = finite(record(selected).row_count) ?? 0;
|
|
132
132
|
return {
|
|
133
133
|
exact: tier.score === 5 ? rowCount : 0,
|
|
134
|
-
comparable: tier.score >
|
|
134
|
+
comparable: tier.score > 1 && tier.score < 5 ? rowCount : 0,
|
|
135
|
+
baseline: tier.score === 1 ? rowCount : 0,
|
|
135
136
|
tier,
|
|
136
137
|
};
|
|
137
138
|
}
|
|
@@ -141,21 +142,67 @@ function matchTier(match) {
|
|
|
141
142
|
const kind = value.match_kind;
|
|
142
143
|
const scope = typeof value.scope === "string" ? value.scope : null;
|
|
143
144
|
if (scope === "same_ticker_exact" || (kind === "context" && !scope)) {
|
|
144
|
-
return { score: 5, basis: "Exact
|
|
145
|
+
return { score: 5, basis: "Exact Setup" };
|
|
145
146
|
}
|
|
146
147
|
if (scope === "cross_ticker_exact_state" || kind === "cross_ticker_context") {
|
|
147
|
-
return { score: 4, basis: "
|
|
148
|
+
return { score: 4, basis: "Cross-Ticker Setup" };
|
|
148
149
|
}
|
|
149
150
|
if (scope === "exact_41_sensor_state" || kind === "strategy") {
|
|
150
|
-
return { score: 3, basis: "
|
|
151
|
+
return { score: 3, basis: "Signal Pattern" };
|
|
151
152
|
}
|
|
152
153
|
if (scope?.startsWith("forward_overlay_") || kind === "forward_overlay_context") {
|
|
153
|
-
return { score: 2, basis: "
|
|
154
|
+
return { score: 2, basis: "Contextual Analogue" };
|
|
154
155
|
}
|
|
155
156
|
if (scope === "all_market_memory_observations" || kind === "side") {
|
|
156
|
-
return { score: 1, basis: "
|
|
157
|
+
return { score: 1, basis: "Direction-Only Baseline" };
|
|
157
158
|
}
|
|
158
|
-
return { score: 0, basis:
|
|
159
|
+
return { score: 0, basis: "No Comparable Evidence" };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function matchShortLabel(score) {
|
|
163
|
+
if (score >= 5) return "Exact Setup";
|
|
164
|
+
if (score === 4) return "Cross-Ticker Setup";
|
|
165
|
+
if (score === 3) return "Signal Pattern";
|
|
166
|
+
if (score === 2) return "Contextual Analogue";
|
|
167
|
+
if (score === 1) return "Direction-Only Baseline";
|
|
168
|
+
return "No Comparable Evidence";
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function matchTone(score) {
|
|
172
|
+
if (score >= 4) return "green";
|
|
173
|
+
if (score >= 2) return "yellow";
|
|
174
|
+
if (score === 1) return "red";
|
|
175
|
+
return "inactive";
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function matchCells(score, colorEnabled) {
|
|
179
|
+
const active = Math.max(0, Math.min(5, Number(score) || 0));
|
|
180
|
+
const activeTone = matchTone(active);
|
|
181
|
+
return Array.from({ length: 5 }, (_, index) => color(
|
|
182
|
+
index < active ? "●" : "○",
|
|
183
|
+
index < active ? activeTone : "inactive",
|
|
184
|
+
colorEnabled,
|
|
185
|
+
)).join("");
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function matchEvidenceLabel(tier, rowCount) {
|
|
189
|
+
const labels = {
|
|
190
|
+
5: "exact observations",
|
|
191
|
+
4: "cross-ticker observations",
|
|
192
|
+
3: "signal-pattern observations",
|
|
193
|
+
2: "context observations",
|
|
194
|
+
1: "baseline observations",
|
|
195
|
+
};
|
|
196
|
+
return labels[tier.score] ? `${rowCount} ${labels[tier.score]}` : "No comparable observations";
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function matchCountMetric(tier, counts) {
|
|
200
|
+
if (tier.score === 5) return { label: "Exact Observations", value: countLabel(counts.exact) };
|
|
201
|
+
if (tier.score === 4) return { label: "Cross-Ticker Sample", value: countLabel(counts.comparable) };
|
|
202
|
+
if (tier.score === 3) return { label: "Signal Pattern Sample", value: countLabel(counts.comparable) };
|
|
203
|
+
if (tier.score === 2) return { label: "Context Sample", value: countLabel(counts.comparable) };
|
|
204
|
+
if (tier.score === 1) return { label: "Baseline Observations", value: countLabel(counts.baseline) };
|
|
205
|
+
return null;
|
|
159
206
|
}
|
|
160
207
|
|
|
161
208
|
function memoryStatus(response) {
|
|
@@ -193,7 +240,7 @@ function lookupMilliseconds(response) {
|
|
|
193
240
|
function humanizeStatus(value) {
|
|
194
241
|
const labels = {
|
|
195
242
|
historical_match: "Historical Match",
|
|
196
|
-
insufficient_context: "
|
|
243
|
+
insufficient_context: "No Comparable Evidence",
|
|
197
244
|
artifact_unavailable: "Reader Unavailable",
|
|
198
245
|
};
|
|
199
246
|
if (typeof value !== "string" || !value) return "Unavailable";
|
|
@@ -202,7 +249,7 @@ function humanizeStatus(value) {
|
|
|
202
249
|
|
|
203
250
|
function memorySummary(status, tier) {
|
|
204
251
|
if (status === "historical_match" && tier.score === 5) return "Match Found";
|
|
205
|
-
if (tier.score > 0) return
|
|
252
|
+
if (tier.score > 0) return tier.basis;
|
|
206
253
|
return humanizeStatus(status);
|
|
207
254
|
}
|
|
208
255
|
|
|
@@ -333,7 +380,7 @@ function ratioLabel(value) {
|
|
|
333
380
|
}
|
|
334
381
|
|
|
335
382
|
function horizonLabel(horizon) {
|
|
336
|
-
return `${horizon}
|
|
383
|
+
return `${horizon} Min`;
|
|
337
384
|
}
|
|
338
385
|
|
|
339
386
|
function setupLine(label, value, tone, enabled) {
|
|
@@ -453,17 +500,10 @@ function gridFrameParts(value) {
|
|
|
453
500
|
|
|
454
501
|
function gridMatchColumns(match, colorEnabled) {
|
|
455
502
|
const tier = matchTier(match);
|
|
456
|
-
const label = tier.score === 5 ? "Exact" : tier.score > 0 ? "Limited" : "No match";
|
|
457
503
|
const rowCount = countLabel(record(match).row_count);
|
|
458
|
-
const countLabelText = tier.score === 5 ? "exact observations" : "comparable observations";
|
|
459
|
-
const cells = Array.from({ length: 5 }, (_, index) => color(
|
|
460
|
-
index < tier.score ? "■" : "□",
|
|
461
|
-
index < tier.score ? "green" : "neutral",
|
|
462
|
-
colorEnabled,
|
|
463
|
-
)).join("");
|
|
464
504
|
return {
|
|
465
|
-
label: `${
|
|
466
|
-
comparable:
|
|
505
|
+
label: `${matchCells(tier.score, colorEnabled)} ${matchShortLabel(tier.score)}`,
|
|
506
|
+
comparable: matchEvidenceLabel(tier, rowCount),
|
|
467
507
|
};
|
|
468
508
|
}
|
|
469
509
|
|
|
@@ -540,7 +580,7 @@ export function buildEvaluationViewModel(response) {
|
|
|
540
580
|
statusReason: memory.reason,
|
|
541
581
|
match: {
|
|
542
582
|
score: tier.score,
|
|
543
|
-
label: tier.score
|
|
583
|
+
label: matchShortLabel(tier.score),
|
|
544
584
|
rowCount: countLabel(record(match).row_count),
|
|
545
585
|
basis: tier.basis,
|
|
546
586
|
},
|
|
@@ -581,7 +621,7 @@ function formatGridEvaluation(response, { colorEnabled = true } = {}) {
|
|
|
581
621
|
const topLines = [
|
|
582
622
|
gridColumns(
|
|
583
623
|
{ text: `${sideText} EVIDENCE`, tone: sideTone(requestedSide) },
|
|
584
|
-
{ text: "
|
|
624
|
+
{ text: "EVIDENCE STRENGTH", tone: "white" },
|
|
585
625
|
colorEnabled,
|
|
586
626
|
),
|
|
587
627
|
gridColumns(
|
|
@@ -700,6 +740,7 @@ export function formatEvaluation(response, { colorEnabled = true, setup = false,
|
|
|
700
740
|
...strategyMixLines(counts.counts, strategyTotal, colorEnabled),
|
|
701
741
|
sectionBottom(colorEnabled),
|
|
702
742
|
];
|
|
743
|
+
const matchCount = matchCountMetric(matchCounts.tier, matchCounts);
|
|
703
744
|
const outcomeGrid = [
|
|
704
745
|
sectionRule("Outcome", colorEnabled),
|
|
705
746
|
outcomeRow("Timeframe", outcomeRows.map((row) => ({ value: horizonLabel(row.horizon), tone: "white" })), colorEnabled),
|
|
@@ -733,10 +774,9 @@ export function formatEvaluation(response, { colorEnabled = true, setup = false,
|
|
|
733
774
|
"",
|
|
734
775
|
"Market Memory",
|
|
735
776
|
compactMetricLine("Status", memorySummary(status, matchCounts.tier), statusTone, colorEnabled),
|
|
736
|
-
compactMetricLine("
|
|
737
|
-
...(
|
|
738
|
-
...(
|
|
739
|
-
...(verbose && matchCounts.tier.basis ? [compactMetricLine("Match Basis", matchCounts.tier.basis, "dim", colorEnabled)] : []),
|
|
777
|
+
compactMetricLine("Evidence Strength", `${matchCounts.tier.score}/5`, matchCounts.tier.score === 5 ? "green" : matchCounts.tier.score > 0 ? "yellow" : "dim", colorEnabled),
|
|
778
|
+
...(matchCount ? [compactMetricLine(matchCount.label, matchCount.value, "bold", colorEnabled)] : []),
|
|
779
|
+
...(verbose && matchCounts.tier.basis ? [compactMetricLine("Evidence Basis", matchCounts.tier.basis, "dim", colorEnabled)] : []),
|
|
740
780
|
compactMetricLine("Window", coverageWindow(response, match), "dim", colorEnabled),
|
|
741
781
|
"",
|
|
742
782
|
"Outcome",
|
|
@@ -755,10 +795,9 @@ export function formatEvaluation(response, { colorEnabled = true, setup = false,
|
|
|
755
795
|
"",
|
|
756
796
|
sectionRule("Market Memory", colorEnabled),
|
|
757
797
|
metricLine("Status", memorySummary(status, matchCounts.tier), statusTone, colorEnabled, 24),
|
|
758
|
-
metricLine("
|
|
759
|
-
...(
|
|
760
|
-
...(
|
|
761
|
-
...(verbose && matchCounts.tier.basis ? [metricLine("Match Basis", matchCounts.tier.basis, "dim", colorEnabled, 24)] : []),
|
|
798
|
+
metricLine("Evidence Strength", `${matchCounts.tier.score}/5`, matchCounts.tier.score === 5 ? "green" : matchCounts.tier.score > 0 ? "yellow" : "dim", colorEnabled, 24),
|
|
799
|
+
...(matchCount ? [metricLine(matchCount.label, matchCount.value, "bold", colorEnabled, 24)] : []),
|
|
800
|
+
...(verbose && matchCounts.tier.basis ? [metricLine("Evidence Basis", matchCounts.tier.basis, "dim", colorEnabled, 24)] : []),
|
|
762
801
|
metricLine("Window", coverageWindow(response, match), "dim", colorEnabled, 24),
|
|
763
802
|
sectionBottom(colorEnabled),
|
|
764
803
|
"",
|
package/src/live-ui.mjs
CHANGED
|
@@ -235,7 +235,7 @@ function renderOutcomeTable(outcomes, colorEnabled) {
|
|
|
235
235
|
const rows = [
|
|
236
236
|
[
|
|
237
237
|
tableValue("Timeframe", "muted", colorEnabled, { bold: true }),
|
|
238
|
-
...outcomes.map((outcome) => tableValue(`${outcome.horizon}
|
|
238
|
+
...outcomes.map((outcome) => tableValue(`${outcome.horizon} Min`, "white", colorEnabled, { bold: true, hAlign: "right" })),
|
|
239
239
|
],
|
|
240
240
|
[
|
|
241
241
|
tableValue("Avg. Return", "muted", colorEnabled, { bold: true }),
|
|
@@ -312,24 +312,30 @@ function bodyLine(content, colorEnabled, layout) {
|
|
|
312
312
|
}
|
|
313
313
|
|
|
314
314
|
function renderHistoricalEvidence(view, colorEnabled) {
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
315
|
+
const score = view.match.score;
|
|
316
|
+
const activeTone = score >= 4 ? "green" : score >= 2 ? "yellow" : score === 1 ? "red" : "inactive";
|
|
317
|
+
const detailLabels = {
|
|
318
|
+
5: "exact observations",
|
|
319
|
+
4: "cross-ticker observations",
|
|
320
|
+
3: "signal-pattern observations",
|
|
321
|
+
2: "context observations",
|
|
322
|
+
1: "baseline observations",
|
|
323
|
+
};
|
|
324
|
+
const matchDetails = detailLabels[score]
|
|
325
|
+
? `${view.match.rowCount} ${detailLabels[score]}`
|
|
326
|
+
: "No comparable observations";
|
|
322
327
|
const matchStrength = [
|
|
323
328
|
Array.from({ length: 5 }, (_, index) => tone(
|
|
324
|
-
|
|
325
|
-
index <
|
|
329
|
+
index < score ? "●" : "○",
|
|
330
|
+
index < score ? activeTone : "inactive",
|
|
326
331
|
colorEnabled,
|
|
327
|
-
)).join("
|
|
328
|
-
tone(
|
|
332
|
+
)).join(""),
|
|
333
|
+
tone(`${score}/5`, score > 0 ? "white" : "muted", colorEnabled, true),
|
|
329
334
|
].join(" ");
|
|
330
335
|
const rows = [
|
|
331
|
-
[tableValue("
|
|
332
|
-
[tableValue("
|
|
336
|
+
[tableValue("Evidence Strength", "muted", colorEnabled, { bold: true }), { content: matchStrength, hAlign: "left" }],
|
|
337
|
+
[tableValue("Evidence Basis", "muted", colorEnabled, { bold: true }), tableValue(view.match.basis ?? "No Comparable Evidence", "neutral", colorEnabled)],
|
|
338
|
+
[tableValue("Observations", "muted", colorEnabled, { bold: true }), tableValue(matchDetails, "neutral", colorEnabled, { bold: true })],
|
|
333
339
|
[tableValue("Date Range", "muted", colorEnabled, { bold: true }), tableValue(view.archiveWindow, "neutral", colorEnabled)],
|
|
334
340
|
];
|
|
335
341
|
return renderTable(rows, tableColumnWidths(rows), colorEnabled, { divider: false });
|