solana-traderclaw 1.0.45 → 1.0.47
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/bin/installer-step-engine.mjs +28 -4
- package/bin/llm-model-preference.mjs +105 -12
- package/bin/openclaw-trader.mjs +60 -4
- package/package.json +1 -1
|
@@ -157,7 +157,12 @@ function normalizeTraderAllowlist(config, pluginId) {
|
|
|
157
157
|
|
|
158
158
|
function stripAnsi(text) {
|
|
159
159
|
if (typeof text !== "string") return text;
|
|
160
|
-
|
|
160
|
+
// Cover all ANSI/VT escape sequences: CSI, OSC, simple escapes, and lone ESC chars.
|
|
161
|
+
return text
|
|
162
|
+
.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "") // CSI sequences (colours, cursor, etc.)
|
|
163
|
+
.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "") // OSC sequences
|
|
164
|
+
.replace(/\x1b[^[\]]/g, "") // other 2-char escape sequences
|
|
165
|
+
.replace(/\x1b/g, ""); // bare ESC survivors
|
|
161
166
|
}
|
|
162
167
|
|
|
163
168
|
/**
|
|
@@ -201,7 +206,7 @@ function commandExists(cmd) {
|
|
|
201
206
|
|
|
202
207
|
function getCommandOutput(cmd) {
|
|
203
208
|
try {
|
|
204
|
-
return execSync(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], shell: true }).trim();
|
|
209
|
+
return execSync(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], shell: true, maxBuffer: 50 * 1024 * 1024 }).trim();
|
|
205
210
|
} catch {
|
|
206
211
|
return null;
|
|
207
212
|
}
|
|
@@ -1184,7 +1189,7 @@ function listProviderModels(provider) {
|
|
|
1184
1189
|
const raw = getCommandOutput(cmd);
|
|
1185
1190
|
if (!raw) return [];
|
|
1186
1191
|
try {
|
|
1187
|
-
const parsed = JSON.parse(raw);
|
|
1192
|
+
const parsed = JSON.parse(stripAnsi(raw));
|
|
1188
1193
|
const models = Array.isArray(parsed?.models) ? parsed.models : [];
|
|
1189
1194
|
return models
|
|
1190
1195
|
.map((entry) => (entry && typeof entry.key === "string" ? entry.key : ""))
|
|
@@ -1195,11 +1200,21 @@ function listProviderModels(provider) {
|
|
|
1195
1200
|
}
|
|
1196
1201
|
|
|
1197
1202
|
function fallbackModelForProvider(provider) {
|
|
1198
|
-
// When `openclaw models list` fails, use current API ids (verify vs provider docs periodically).
|
|
1199
1203
|
if (provider === "anthropic") return "anthropic/claude-sonnet-4-6";
|
|
1200
1204
|
if (provider === "openai") return "openai/gpt-5.4";
|
|
1201
1205
|
if (provider === "openai-codex") return "openai-codex/gpt-5.4";
|
|
1202
1206
|
if (provider === "google" || provider === "google-vertex") return "google/gemini-2.5-flash";
|
|
1207
|
+
if (provider === "xai") return "xai/grok-4";
|
|
1208
|
+
if (provider === "deepseek") return "deepseek/deepseek-chat";
|
|
1209
|
+
if (provider === "together") return "together/moonshotai/Kimi-K2.5";
|
|
1210
|
+
if (provider === "groq") return "groq/llama-4-scout-17b-16e-instruct";
|
|
1211
|
+
if (provider === "mistral") return "mistral/mistral-large-latest";
|
|
1212
|
+
if (provider === "perplexity") return "perplexity/sonar-pro";
|
|
1213
|
+
if (provider === "nvidia") return "nvidia/llama-3.3-70b-instruct";
|
|
1214
|
+
if (provider === "minimax") return "minimax/MiniMax-M2.7";
|
|
1215
|
+
if (provider === "moonshot") return "moonshot/kimi-k2";
|
|
1216
|
+
if (provider === "cerebras") return "cerebras/llama-4-scout-17b-16e-instruct";
|
|
1217
|
+
if (provider === "qwen") return "qwen/qwen3-235b-a22b";
|
|
1203
1218
|
return `${provider}/default`;
|
|
1204
1219
|
}
|
|
1205
1220
|
|
|
@@ -1210,6 +1225,15 @@ function providerEnvKey(provider) {
|
|
|
1210
1225
|
if (provider === "groq") return "GROQ_API_KEY";
|
|
1211
1226
|
if (provider === "mistral") return "MISTRAL_API_KEY";
|
|
1212
1227
|
if (provider === "google" || provider === "google-vertex") return "GEMINI_API_KEY";
|
|
1228
|
+
if (provider === "xai") return "XAI_API_KEY";
|
|
1229
|
+
if (provider === "deepseek") return "DEEPSEEK_API_KEY";
|
|
1230
|
+
if (provider === "together") return "TOGETHER_API_KEY";
|
|
1231
|
+
if (provider === "perplexity") return "PERPLEXITY_API_KEY";
|
|
1232
|
+
if (provider === "nvidia") return "NVIDIA_API_KEY";
|
|
1233
|
+
if (provider === "minimax") return "MINIMAX_API_KEY";
|
|
1234
|
+
if (provider === "moonshot") return "MOONSHOT_API_KEY";
|
|
1235
|
+
if (provider === "cerebras") return "CEREBRAS_API_KEY";
|
|
1236
|
+
if (provider === "qwen") return "DASHSCOPE_API_KEY";
|
|
1213
1237
|
return "";
|
|
1214
1238
|
}
|
|
1215
1239
|
|
|
@@ -2,13 +2,32 @@
|
|
|
2
2
|
* Ranks OpenClaw model keys so defaults pick current, working IDs — not alphabetically-first
|
|
3
3
|
* or legacy IDs that "win" only because of a large YYYYMMDD suffix in the name.
|
|
4
4
|
*
|
|
5
|
-
* References (verify periodically): Anthropic models overview, OpenAI models docs.
|
|
5
|
+
* References (verify periodically): Anthropic models overview, OpenAI models docs, xAI docs.
|
|
6
|
+
* Last verified: 2026-03-29.
|
|
6
7
|
*/
|
|
7
8
|
|
|
8
|
-
/** IDs that
|
|
9
|
+
/** IDs that appear in catalogs but are retired, deprecated, or misbehave for chat/agent use */
|
|
9
10
|
export const KNOWN_PROBLEMATIC_MODEL_IDS = new Set([
|
|
10
11
|
"anthropic/claude-3-5-haiku-20241022",
|
|
11
12
|
"anthropic/claude-3-haiku-20240307",
|
|
13
|
+
"anthropic/claude-3-opus-20240229",
|
|
14
|
+
"anthropic/claude-3-sonnet-20240229",
|
|
15
|
+
"anthropic/claude-3-5-sonnet-20240620",
|
|
16
|
+
"openai/gpt-4o",
|
|
17
|
+
"openai/gpt-4o-mini",
|
|
18
|
+
"openai/gpt-4-turbo",
|
|
19
|
+
"openai/gpt-4",
|
|
20
|
+
"openai/gpt-3.5-turbo",
|
|
21
|
+
"openai/gpt-5",
|
|
22
|
+
"openai/gpt-5.1",
|
|
23
|
+
"openai/gpt-5.1-codex",
|
|
24
|
+
"openai/gpt-5.1-codex-max",
|
|
25
|
+
"openai/gpt-5.1-codex-mini",
|
|
26
|
+
"openai/gpt-5.1-instant",
|
|
27
|
+
"openai-codex/gpt-5.1",
|
|
28
|
+
"openai-codex/gpt-5.1-codex",
|
|
29
|
+
"openai-codex/gpt-5.1-codex-max",
|
|
30
|
+
"openai-codex/gpt-5.1-codex-mini",
|
|
12
31
|
]);
|
|
13
32
|
|
|
14
33
|
const VARIANT_WEIGHT = { sonnet: 80_000, opus: 60_000, haiku: 40_000 };
|
|
@@ -56,25 +75,35 @@ function anthropicPreferenceScore(modelId) {
|
|
|
56
75
|
if (!meta) {
|
|
57
76
|
return 1_000_000 + tieBreakerSnapshot(local);
|
|
58
77
|
}
|
|
59
|
-
// Generation must dominate: a dated Haiku 4.5 snapshot must not beat Sonnet 4.6 (see Anthropic model lineup).
|
|
60
78
|
const generation = meta.major * 10_000 + meta.minor;
|
|
61
79
|
const v = VARIANT_WEIGHT[meta.variant] || 0;
|
|
62
80
|
return generation * 1_000_000_000_000 + v + meta.snapshot;
|
|
63
81
|
}
|
|
64
82
|
|
|
65
83
|
function openaiFamilyScore(local) {
|
|
66
|
-
// Prefer GPT-5.x over 4.x over 3.5; higher minor (5.4 vs 5.2) wins; bare gpt-5 below explicit minors.
|
|
67
84
|
const g5 = local.match(/^gpt-5(?:\.(\d+))?/);
|
|
68
85
|
if (g5) {
|
|
69
86
|
const sub = g5[1] ? Number.parseInt(g5[1], 10) : 0;
|
|
70
|
-
|
|
87
|
+
let s = 500 * 1_000_000_000 + sub * 1_000_000;
|
|
88
|
+
if (local.includes("pro") || local.includes("thinking")) s += 400_000;
|
|
89
|
+
else if (local.includes("nano")) s -= 200_000;
|
|
90
|
+
else if (local.includes("mini")) s -= 100_000;
|
|
91
|
+
else if (local.includes("instant")) s -= 150_000;
|
|
92
|
+
return s;
|
|
71
93
|
}
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
94
|
+
const oSeries = local.match(/^o(\d+)/);
|
|
95
|
+
if (oSeries) {
|
|
96
|
+
const gen = Number.parseInt(oSeries[1], 10);
|
|
97
|
+
let score = 490 * 1_000_000_000 + gen * 1_000_000;
|
|
98
|
+
if (local.includes("mini")) score -= 500_000;
|
|
99
|
+
if (local.includes("pro")) score += 200_000;
|
|
100
|
+
return score;
|
|
101
|
+
}
|
|
102
|
+
if (local.startsWith("gpt-4o-mini")) return 380 * 1_000_000_000;
|
|
103
|
+
if (local.startsWith("gpt-4o")) return 385 * 1_000_000_000;
|
|
104
|
+
if (local.includes("gpt-4-turbo")) return 370 * 1_000_000_000;
|
|
105
|
+
if (local.startsWith("gpt-4")) return 360 * 1_000_000_000;
|
|
106
|
+
if (local.includes("gpt-3.5")) return 250 * 1_000_000_000;
|
|
78
107
|
return 100 * 1_000_000_000;
|
|
79
108
|
}
|
|
80
109
|
|
|
@@ -83,16 +112,74 @@ function openaiPreferenceScore(modelId) {
|
|
|
83
112
|
const local = raw.includes("/") ? raw.split("/").slice(1).join("/") : raw;
|
|
84
113
|
let score = openaiFamilyScore(local);
|
|
85
114
|
score += tieBreakerSnapshot(local);
|
|
86
|
-
// Small bump for non-preview stable names
|
|
87
115
|
if (local.includes("preview")) score -= 50_000_000;
|
|
88
116
|
return score;
|
|
89
117
|
}
|
|
90
118
|
|
|
119
|
+
function xaiPreferenceScore(modelId) {
|
|
120
|
+
const local = stripPrefix("xai", modelId);
|
|
121
|
+
const grokMatch = local.match(/^grok-(\d+)(?:\.(\d+))?/);
|
|
122
|
+
if (!grokMatch) return 100_000_000 + tieBreakerSnapshot(modelId);
|
|
123
|
+
const major = Number.parseInt(grokMatch[1], 10);
|
|
124
|
+
const minor = grokMatch[2] ? Number.parseInt(grokMatch[2], 10) : 0;
|
|
125
|
+
let score = (major * 100 + minor) * 1_000_000_000;
|
|
126
|
+
if (local.includes("non-reasoning")) score -= 100_000;
|
|
127
|
+
else if (local.includes("reasoning")) score += 200_000;
|
|
128
|
+
if (local.includes("fast")) score -= 50_000;
|
|
129
|
+
if (local.includes("beta")) score -= 500_000;
|
|
130
|
+
if (local.includes("code")) score += 100_000;
|
|
131
|
+
score += tieBreakerSnapshot(modelId);
|
|
132
|
+
return score;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function deepseekPreferenceScore(modelId) {
|
|
136
|
+
const local = stripPrefix("deepseek", modelId);
|
|
137
|
+
if (local.includes("reasoner")) return 600_000_000;
|
|
138
|
+
if (local.includes("chat")) return 500_000_000;
|
|
139
|
+
return 100_000_000 + tieBreakerSnapshot(modelId);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function googlePreferenceScore(modelId) {
|
|
143
|
+
const local = stripPrefix("google", modelId).replace(/^google-vertex\//, "");
|
|
144
|
+
const gemini = local.match(/gemini-(\d+)(?:\.(\d+))?/);
|
|
145
|
+
if (!gemini) return 100_000_000 + tieBreakerSnapshot(modelId);
|
|
146
|
+
const major = Number.parseInt(gemini[1], 10);
|
|
147
|
+
const minor = gemini[2] ? Number.parseInt(gemini[2], 10) : 0;
|
|
148
|
+
let score = (major * 100 + minor) * 1_000_000_000;
|
|
149
|
+
if (local.includes("pro")) score += 200_000_000;
|
|
150
|
+
else if (local.includes("ultra")) score += 300_000_000;
|
|
151
|
+
else if (local.includes("flash")) score += 100_000_000;
|
|
152
|
+
else if (local.includes("nano")) score += 50_000_000;
|
|
153
|
+
if (local.includes("preview") || local.includes("experimental")) score -= 50_000_000;
|
|
154
|
+
if (local.includes("thinking")) score += 10_000_000;
|
|
155
|
+
if (local.includes("latest")) score += 5_000_000;
|
|
156
|
+
score += tieBreakerSnapshot(modelId);
|
|
157
|
+
return score;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function extractParamCountBonus(local) {
|
|
161
|
+
const m = local.match(/(\d+)b(?:\b|-)/i);
|
|
162
|
+
if (!m) return 0;
|
|
163
|
+
const b = Number.parseInt(m[1], 10);
|
|
164
|
+
return Math.min(b, 2000) * 100;
|
|
165
|
+
}
|
|
166
|
+
|
|
91
167
|
function genericPreferenceScore(provider, modelId) {
|
|
92
168
|
const local = stripPrefix(provider, modelId);
|
|
93
169
|
let score = tieBreakerSnapshot(modelId);
|
|
94
170
|
if (local.includes("latest")) score += 500_000_000;
|
|
171
|
+
if (local.includes("pro") || local.includes("large")) score += 100_000_000;
|
|
95
172
|
if (local.includes("preview") || local.includes("deprecated")) score -= 200_000_000;
|
|
173
|
+
if (local.includes("beta")) score -= 50_000_000;
|
|
174
|
+
const verMatch = local.match(/(?:^|[a-z-])(\d+)(?:\.(\d+))?/);
|
|
175
|
+
if (verMatch) {
|
|
176
|
+
const maj = Number.parseInt(verMatch[1], 10);
|
|
177
|
+
const min = verMatch[2] ? Number.parseInt(verMatch[2], 10) : 0;
|
|
178
|
+
if (maj <= 99) {
|
|
179
|
+
score += (maj * 100 + min) * 1_000_000;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
score += extractParamCountBonus(local);
|
|
96
183
|
return score;
|
|
97
184
|
}
|
|
98
185
|
|
|
@@ -111,6 +198,12 @@ export function modelPreferenceScore(provider, modelId) {
|
|
|
111
198
|
score += anthropicPreferenceScore(id);
|
|
112
199
|
} else if (provider === "openai" || provider === "openai-codex") {
|
|
113
200
|
score += openaiPreferenceScore(id);
|
|
201
|
+
} else if (provider === "google" || provider === "google-vertex") {
|
|
202
|
+
score += googlePreferenceScore(id);
|
|
203
|
+
} else if (provider === "xai") {
|
|
204
|
+
score += xaiPreferenceScore(id);
|
|
205
|
+
} else if (provider === "deepseek") {
|
|
206
|
+
score += deepseekPreferenceScore(id);
|
|
114
207
|
} else {
|
|
115
208
|
score += genericPreferenceScore(provider, id);
|
|
116
209
|
}
|
package/bin/openclaw-trader.mjs
CHANGED
|
@@ -71,9 +71,18 @@ function commandExists(cmd) {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
function stripAnsi(text) {
|
|
75
|
+
if (typeof text !== "string") return text;
|
|
76
|
+
return text
|
|
77
|
+
.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "")
|
|
78
|
+
.replace(/\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g, "")
|
|
79
|
+
.replace(/\x1b[^[\]]/g, "")
|
|
80
|
+
.replace(/\x1b/g, "");
|
|
81
|
+
}
|
|
82
|
+
|
|
74
83
|
function getCommandOutput(cmd) {
|
|
75
84
|
try {
|
|
76
|
-
return execSync(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], shell: true }).trim();
|
|
85
|
+
return execSync(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"], shell: true, maxBuffer: 50 * 1024 * 1024 }).trim();
|
|
77
86
|
} catch {
|
|
78
87
|
return null;
|
|
79
88
|
}
|
|
@@ -1725,6 +1734,17 @@ function loadWizardLlmCatalog() {
|
|
|
1725
1734
|
"mistral",
|
|
1726
1735
|
"google",
|
|
1727
1736
|
"google-vertex",
|
|
1737
|
+
"xai",
|
|
1738
|
+
"deepseek",
|
|
1739
|
+
"together",
|
|
1740
|
+
"perplexity",
|
|
1741
|
+
"amazon-bedrock",
|
|
1742
|
+
"vercel-ai-gateway",
|
|
1743
|
+
"minimax",
|
|
1744
|
+
"moonshot",
|
|
1745
|
+
"nvidia",
|
|
1746
|
+
"qwen",
|
|
1747
|
+
"cerebras",
|
|
1728
1748
|
]);
|
|
1729
1749
|
const fallback = {
|
|
1730
1750
|
source: "fallback",
|
|
@@ -1737,6 +1757,30 @@ function loadWizardLlmCatalog() {
|
|
|
1737
1757
|
id: "openai",
|
|
1738
1758
|
models: [{ id: "openai/gpt-5.4", name: "GPT-5.4" }],
|
|
1739
1759
|
},
|
|
1760
|
+
{
|
|
1761
|
+
id: "xai",
|
|
1762
|
+
models: [{ id: "xai/grok-4", name: "Grok 4" }],
|
|
1763
|
+
},
|
|
1764
|
+
{
|
|
1765
|
+
id: "deepseek",
|
|
1766
|
+
models: [{ id: "deepseek/deepseek-chat", name: "DeepSeek Chat (V3.2)" }],
|
|
1767
|
+
},
|
|
1768
|
+
{
|
|
1769
|
+
id: "google",
|
|
1770
|
+
models: [{ id: "google/gemini-2.5-flash", name: "Gemini 2.5 Flash" }],
|
|
1771
|
+
},
|
|
1772
|
+
{
|
|
1773
|
+
id: "groq",
|
|
1774
|
+
models: [{ id: "groq/llama-4-scout-17b-16e-instruct", name: "Llama 4 Scout" }],
|
|
1775
|
+
},
|
|
1776
|
+
{
|
|
1777
|
+
id: "openrouter",
|
|
1778
|
+
models: [{ id: "openrouter/anthropic/claude-sonnet-4-6", name: "Claude Sonnet 4.6 (via OpenRouter)" }],
|
|
1779
|
+
},
|
|
1780
|
+
{
|
|
1781
|
+
id: "mistral",
|
|
1782
|
+
models: [{ id: "mistral/mistral-large-latest", name: "Mistral Large" }],
|
|
1783
|
+
},
|
|
1740
1784
|
],
|
|
1741
1785
|
};
|
|
1742
1786
|
|
|
@@ -1748,8 +1792,10 @@ function loadWizardLlmCatalog() {
|
|
|
1748
1792
|
const raw = execSync("openclaw models list --all --json", {
|
|
1749
1793
|
encoding: "utf-8",
|
|
1750
1794
|
stdio: ["ignore", "pipe", "pipe"],
|
|
1795
|
+
maxBuffer: 50 * 1024 * 1024,
|
|
1796
|
+
timeout: 30_000,
|
|
1751
1797
|
});
|
|
1752
|
-
const parsed = JSON.parse(raw);
|
|
1798
|
+
const parsed = JSON.parse(stripAnsi(raw));
|
|
1753
1799
|
const models = Array.isArray(parsed?.models) ? parsed.models : [];
|
|
1754
1800
|
const providerMap = new Map();
|
|
1755
1801
|
for (const entry of models) {
|
|
@@ -1791,9 +1837,15 @@ function loadWizardLlmCatalog() {
|
|
|
1791
1837
|
generatedAt: new Date().toISOString(),
|
|
1792
1838
|
};
|
|
1793
1839
|
} catch (err) {
|
|
1840
|
+
const detail = err?.message || String(err);
|
|
1841
|
+
const isBufferErr = detail.includes("maxBuffer") || detail.includes("ENOBUFS");
|
|
1842
|
+
const hint = isBufferErr
|
|
1843
|
+
? " (stdout exceeded buffer — OpenClaw model catalog may have grown; this version raises the limit)"
|
|
1844
|
+
: "";
|
|
1845
|
+
console.error(`[traderclaw] loadWizardLlmCatalog failed${hint}: ${detail.slice(0, 500)}`);
|
|
1794
1846
|
return {
|
|
1795
1847
|
...fallback,
|
|
1796
|
-
warning: `openclaw_models_list_failed: ${
|
|
1848
|
+
warning: `openclaw_models_list_failed: ${detail}`,
|
|
1797
1849
|
};
|
|
1798
1850
|
}
|
|
1799
1851
|
}
|
|
@@ -2154,7 +2206,11 @@ function wizardHtml(defaults) {
|
|
|
2154
2206
|
}
|
|
2155
2207
|
setSelectOptions(llmProviderEl, providers, "${defaults.llmProvider}");
|
|
2156
2208
|
refreshModelOptions("${defaults.llmModel}");
|
|
2157
|
-
|
|
2209
|
+
const isFallback = llmCatalog.source === "fallback";
|
|
2210
|
+
const catalogMsg = isFallback
|
|
2211
|
+
? "Showing safe defaults only (could not load full OpenClaw catalog" + (llmCatalog.warning ? ": " + llmCatalog.warning : "") + "). These providers still work — pick one and paste your credential."
|
|
2212
|
+
: "LLM providers loaded. Select provider and paste credential to continue. Model selection is optional.";
|
|
2213
|
+
setLlmCatalogReady(true, catalogMsg, isFallback);
|
|
2158
2214
|
} catch (err) {
|
|
2159
2215
|
setLlmCatalogReady(false, "Failed to load LLM providers. Check OpenClaw and reload this page.", true);
|
|
2160
2216
|
manualEl.textContent = "Failed to load LLM provider catalog: " + (err && err.message ? err.message : String(err));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "solana-traderclaw",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.47",
|
|
4
4
|
"description": "TraderClaw V1-Upgraded — Solana trading for OpenClaw with intelligence lab, tool envelopes, prompt scrubbing, read-only X social intel, and split skill docs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|