@raintree-technology/perps 0.1.2 → 0.1.3
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/README.md +30 -2
- package/dist/cli/experience.js +0 -1
- package/dist/cli/program.js +28 -5
- package/dist/index.js +35 -1
- package/dist/lib/exit-codes.js +5 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# perps
|
|
2
2
|
|
|
3
|
-
Universal CLI for perpetual DEXes
|
|
3
|
+
Universal CLI for perpetual DEXes.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/raintree-technology/perps/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/@raintree-technology/perps)
|
|
@@ -12,6 +12,22 @@ npm install -g @raintree-technology/perps
|
|
|
12
12
|
perps --help
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## Install Paths
|
|
16
|
+
|
|
17
|
+
Canonical install path:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g @raintree-technology/perps
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
GitHub install path (for source snapshots and pre-release testing):
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install github:raintree-technology/perps
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The package includes lifecycle build hooks so git installs produce runnable CLI artifacts (`dist/`) automatically.
|
|
30
|
+
|
|
15
31
|
## Supported Exchanges
|
|
16
32
|
|
|
17
33
|
| Exchange | Chain | Status | Onboarding |
|
|
@@ -136,6 +152,18 @@ perps doctor # Health check
|
|
|
136
152
|
|
|
137
153
|
Every command supports `--json` for machine-readable output and `--help` for usage details.
|
|
138
154
|
|
|
155
|
+
Agent-friendly mode:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Non-interactive execution
|
|
159
|
+
perps setup wizard --yes --json
|
|
160
|
+
|
|
161
|
+
# Machine-readable responses with schema version
|
|
162
|
+
perps markets ls --json
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
JSON payloads are schema-versioned, and failures return deterministic exit codes.
|
|
166
|
+
|
|
139
167
|
## Exit Codes
|
|
140
168
|
|
|
141
169
|
| Code | Meaning |
|
|
@@ -169,7 +197,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. Please read our [Code of
|
|
|
169
197
|
|
|
170
198
|
## Author
|
|
171
199
|
|
|
172
|
-
[Raintree Technology](https://raintree.technology)
|
|
200
|
+
[Raintree Technology](https://raintree.technology)
|
|
173
201
|
|
|
174
202
|
## License
|
|
175
203
|
|
package/dist/cli/experience.js
CHANGED
|
@@ -107,7 +107,6 @@ export function printSessionBanner(args) {
|
|
|
107
107
|
for (const line of getPerpsAsciiMark()) {
|
|
108
108
|
console.log(highlighter.brand(line));
|
|
109
109
|
}
|
|
110
|
-
console.log(highlighter.dim("by Raintree Technology"));
|
|
111
110
|
console.log("");
|
|
112
111
|
console.log(`${highlighter.dim("mode")} ${networkTag} ${highlighter.dim("exchange")} ${exchangeTag}`);
|
|
113
112
|
console.log(`${highlighter.dim("command")} ${commandTag} ${highlighter.dim("version")} ${highlighter.dim(`v${args.version}`)}`);
|
package/dist/cli/program.js
CHANGED
|
@@ -8,6 +8,8 @@ import { createContext } from "./context.js";
|
|
|
8
8
|
import { highlighter, printCommandCompletion, printSessionBanner } from "./experience.js";
|
|
9
9
|
import { commandPathFromCommand, resolveTestnetMode } from "./network-defaults.js";
|
|
10
10
|
import { outputError } from "./output.js";
|
|
11
|
+
import { inferExitCode } from "../lib/exit-codes.js";
|
|
12
|
+
import { withJsonContract } from "../lib/contracts.js";
|
|
11
13
|
const require = createRequire(import.meta.url);
|
|
12
14
|
const pkg = require("../../package.json");
|
|
13
15
|
const commandMeta = new WeakMap();
|
|
@@ -30,6 +32,7 @@ export function createProgram() {
|
|
|
30
32
|
.description("Universal CLI for perpetual DEXes")
|
|
31
33
|
.showSuggestionAfterError(true)
|
|
32
34
|
.showHelpAfterError()
|
|
35
|
+
.exitOverride()
|
|
33
36
|
.version(pkg.version)
|
|
34
37
|
.option("--json", "Output in JSON format", false)
|
|
35
38
|
.option("--human", "Enable human-first output UX (banner, timing, rich formatting)", false)
|
|
@@ -62,17 +65,37 @@ Examples:
|
|
|
62
65
|
setExchange(opts.exchange);
|
|
63
66
|
}
|
|
64
67
|
catch (err) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
69
|
+
const exitCode = inferExitCode(err);
|
|
70
|
+
if (opts.json) {
|
|
71
|
+
console.error(JSON.stringify(withJsonContract("perps.error", {
|
|
72
|
+
status: "error",
|
|
73
|
+
error: { message, exitCode },
|
|
74
|
+
}), null, 2));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
outputError(message);
|
|
78
|
+
console.error(highlighter.dim(`Available exchanges: ${getAvailableExchanges().join(", ")}`));
|
|
79
|
+
}
|
|
80
|
+
process.exit(exitCode);
|
|
68
81
|
}
|
|
69
82
|
let config;
|
|
70
83
|
try {
|
|
71
84
|
config = loadConfig(isTestnet, opts.exchange);
|
|
72
85
|
}
|
|
73
86
|
catch (err) {
|
|
74
|
-
|
|
75
|
-
|
|
87
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
88
|
+
const exitCode = inferExitCode(err);
|
|
89
|
+
if (opts.json) {
|
|
90
|
+
console.error(JSON.stringify(withJsonContract("perps.error", {
|
|
91
|
+
status: "error",
|
|
92
|
+
error: { message, exitCode },
|
|
93
|
+
}), null, 2));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
outputError(message);
|
|
97
|
+
}
|
|
98
|
+
process.exit(exitCode);
|
|
76
99
|
}
|
|
77
100
|
const context = createContext(config);
|
|
78
101
|
// Store metadata on the root command
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createProgram } from "./cli/program.js";
|
|
3
|
+
import { withJsonContract } from "./lib/contracts.js";
|
|
4
|
+
import { inferExitCode } from "./lib/exit-codes.js";
|
|
5
|
+
const isJsonMode = process.argv.includes("--json");
|
|
3
6
|
const program = createProgram();
|
|
4
|
-
|
|
7
|
+
if (isJsonMode) {
|
|
8
|
+
program.configureOutput({
|
|
9
|
+
writeOut: () => undefined,
|
|
10
|
+
writeErr: () => undefined,
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
await program.parseAsync(process.argv);
|
|
15
|
+
}
|
|
16
|
+
catch (err) {
|
|
17
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
18
|
+
const commanderExitCode = typeof err === "object" && err !== null && "exitCode" in err
|
|
19
|
+
? Number(err.exitCode)
|
|
20
|
+
: Number.NaN;
|
|
21
|
+
const commanderCode = typeof err === "object" && err !== null && "code" in err
|
|
22
|
+
? String(err.code ?? "")
|
|
23
|
+
: "";
|
|
24
|
+
const exitCode = Number.isFinite(commanderExitCode) && commanderExitCode === 0
|
|
25
|
+
? 0
|
|
26
|
+
: commanderCode.startsWith("commander.")
|
|
27
|
+
? inferExitCode(err)
|
|
28
|
+
: Number.isFinite(commanderExitCode)
|
|
29
|
+
? commanderExitCode
|
|
30
|
+
: inferExitCode(err);
|
|
31
|
+
if (isJsonMode && exitCode !== 0) {
|
|
32
|
+
console.error(JSON.stringify(withJsonContract("perps.error", {
|
|
33
|
+
status: "error",
|
|
34
|
+
error: { message, exitCode },
|
|
35
|
+
}), null, 2));
|
|
36
|
+
}
|
|
37
|
+
process.exit(exitCode);
|
|
38
|
+
}
|
package/dist/lib/exit-codes.js
CHANGED
|
@@ -25,7 +25,11 @@ export function inferExitCode(err) {
|
|
|
25
25
|
const message = err instanceof Error ? err.message.toLowerCase() : String(err).toLowerCase();
|
|
26
26
|
if (message.includes("must be") ||
|
|
27
27
|
message.includes("invalid") ||
|
|
28
|
-
message.includes("use --yes with --json")
|
|
28
|
+
message.includes("use --yes with --json") ||
|
|
29
|
+
message.includes("unknown option") ||
|
|
30
|
+
message.includes("too many arguments") ||
|
|
31
|
+
message.includes("missing required argument") ||
|
|
32
|
+
message.includes("option argument missing")) {
|
|
29
33
|
return EXIT_CODES.VALIDATION_ERROR;
|
|
30
34
|
}
|
|
31
35
|
if (message.includes("not configured") ||
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@raintree-technology/perps",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Universal CLI for perpetual DEXes",
|
|
5
5
|
"author": "Raintree Technology (https://raintree.technology)",
|
|
6
6
|
"contributors": [
|
|
@@ -63,6 +63,8 @@
|
|
|
63
63
|
"sideEffects": false,
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "tsc",
|
|
66
|
+
"prepare": "npm run build",
|
|
67
|
+
"prepack": "npm run build",
|
|
66
68
|
"dev": "tsx src/index.ts",
|
|
67
69
|
"typecheck": "tsc --noEmit",
|
|
68
70
|
"smoke": "node scripts/smoke.mjs",
|
|
@@ -82,7 +84,7 @@
|
|
|
82
84
|
"lint:fix": "biome lint --write src scripts",
|
|
83
85
|
"publint": "publint",
|
|
84
86
|
"attw": "attw --pack . --profile esm-only",
|
|
85
|
-
"pack:check": "npm pack --dry-run",
|
|
87
|
+
"pack:check": "npm run build && npm pack --dry-run && node scripts/verify-pack.mjs",
|
|
86
88
|
"prepublishOnly": "npm run build && npm run publint && npm run attw"
|
|
87
89
|
},
|
|
88
90
|
"dependencies": {
|
|
@@ -105,6 +107,7 @@
|
|
|
105
107
|
"zod": "^3.24.0"
|
|
106
108
|
},
|
|
107
109
|
"devDependencies": {
|
|
110
|
+
"next": "^16.1.6",
|
|
108
111
|
"@arethetypeswrong/cli": "^0.18.2",
|
|
109
112
|
"@biomejs/biome": "^1.9.4",
|
|
110
113
|
"@types/better-sqlite3": "^7.6.13",
|