@alchemy/cli 0.2.0 → 0.2.1
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 +8 -1
- package/dist/{chunk-MAKSV2EA.js → chunk-HBRTTBCY.js} +1 -1
- package/dist/{chunk-VRBWUQHA.js → chunk-SDUCDSCZ.js} +108 -1
- package/dist/{chunk-VD5WQHLQ.js → chunk-XP5KF4W2.js} +1 -1
- package/dist/index.js +67 -11
- package/dist/{interactive-CP6E23OD.js → interactive-L7N4HI7K.js} +11 -3
- package/dist/{onboarding-IKIXUTY7.js → onboarding-YA32OJOT.js} +10 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -57,6 +57,9 @@ alchemy
|
|
|
57
57
|
|
|
58
58
|
# Agent/script-friendly command
|
|
59
59
|
alchemy balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --json --no-interactive
|
|
60
|
+
|
|
61
|
+
# Agent checks whether a newer CLI version is available
|
|
62
|
+
alchemy update-check --json --no-interactive
|
|
60
63
|
```
|
|
61
64
|
|
|
62
65
|
#### Agent bootstrap
|
|
@@ -70,6 +73,8 @@ alchemy --json agent-prompt
|
|
|
70
73
|
|
|
71
74
|
This returns a single JSON document with execution policy, preflight instructions, auth matrix, the full command tree with all arguments and options, error codes with recovery actions, and example invocations. No external docs required.
|
|
72
75
|
|
|
76
|
+
Agents can also call `alchemy --json --no-interactive update-check` to retrieve the current CLI version, latest known version, and install command for upgrades.
|
|
77
|
+
|
|
73
78
|
## Command Reference
|
|
74
79
|
|
|
75
80
|
Run commands as `alchemy <command>`.
|
|
@@ -151,6 +156,7 @@ Use `alchemy help` or `alchemy help <command>` for generated command help.
|
|
|
151
156
|
| `apps origin-allowlist <id>` | Updates app origin allowlist | `alchemy apps origin-allowlist <app-id> --origins https://example.com` |
|
|
152
157
|
| `apps ip-allowlist <id>` | Updates app IP allowlist | `alchemy apps ip-allowlist <app-id> --ips 1.2.3.4,5.6.7.8` |
|
|
153
158
|
| `setup status` | Shows setup status + next commands | `alchemy setup status` |
|
|
159
|
+
| `update-check` | Checks whether a newer CLI version is available | `alchemy update-check --json --no-interactive` |
|
|
154
160
|
| `config set ...` | Sets config values | `alchemy config set api-key <key>` |
|
|
155
161
|
| `config get <key>` | Gets one config value | `alchemy config get network` |
|
|
156
162
|
| `config list` | Lists all config values | `alchemy config list` |
|
|
@@ -180,7 +186,7 @@ These apply to all commands.
|
|
|
180
186
|
|---|---|---|
|
|
181
187
|
| `--json` | — | Force JSON output |
|
|
182
188
|
| `-q, --quiet` | — | Suppress non-essential output |
|
|
183
|
-
|
|
|
189
|
+
| `--verbose` | — | Enable verbose output |
|
|
184
190
|
| `--no-color` | `NO_COLOR` | Disable color output |
|
|
185
191
|
| `--reveal` | — | Show secrets in plain text (TTY only) |
|
|
186
192
|
|
|
@@ -317,6 +323,7 @@ Use `--no-interactive` to disable REPL/prompts in automation.
|
|
|
317
323
|
|
|
318
324
|
- TTY: formatted human output
|
|
319
325
|
- Non-TTY: JSON output (script-friendly)
|
|
326
|
+
- `-v`, `--version`: prints the CLI version
|
|
320
327
|
- `--json`: forces JSON output in any context
|
|
321
328
|
- `--verbose` or `alchemy config set verbose true`: includes richer payload output on supported commands
|
|
322
329
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
3
3
|
import {
|
|
4
4
|
isInteractiveAllowed
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-SDUCDSCZ.js";
|
|
6
6
|
|
|
7
7
|
// src/lib/networks.ts
|
|
8
8
|
var TESTNET_TOKEN_RE = /(testnet|sepolia|holesky|hoodi|devnet|minato|amoy|fuji|saigon|cardona|aeneid|curtis|chiado|cassiopeia|blaze|ropsten|signet|mocha|fam|bepolia)$/i;
|
|
@@ -1047,6 +1047,109 @@ function isInteractiveAllowed(program) {
|
|
|
1047
1047
|
return true;
|
|
1048
1048
|
}
|
|
1049
1049
|
|
|
1050
|
+
// src/lib/update-check.ts
|
|
1051
|
+
import { execFileSync } from "child_process";
|
|
1052
|
+
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
1053
|
+
import { dirname as dirname2 } from "path";
|
|
1054
|
+
var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
1055
|
+
var UPDATE_INSTALL_COMMAND = "npm i -g @alchemy/cli";
|
|
1056
|
+
function cachePath() {
|
|
1057
|
+
return configPath().replace(/config\.json$/, ".update-check");
|
|
1058
|
+
}
|
|
1059
|
+
function readCache() {
|
|
1060
|
+
try {
|
|
1061
|
+
return JSON.parse(readFileSync2(cachePath(), "utf-8"));
|
|
1062
|
+
} catch {
|
|
1063
|
+
return null;
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
function writeCache(cache) {
|
|
1067
|
+
try {
|
|
1068
|
+
const p = cachePath();
|
|
1069
|
+
mkdirSync2(dirname2(p), { recursive: true });
|
|
1070
|
+
writeFileSync2(p, JSON.stringify(cache), { mode: 384 });
|
|
1071
|
+
} catch {
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
function fetchLatestVersion() {
|
|
1075
|
+
try {
|
|
1076
|
+
const result = execFileSync("npm", ["view", "@alchemy/cli", "version"], {
|
|
1077
|
+
encoding: "utf-8",
|
|
1078
|
+
timeout: 5e3,
|
|
1079
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
1080
|
+
});
|
|
1081
|
+
return result.trim() || null;
|
|
1082
|
+
} catch {
|
|
1083
|
+
return null;
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
function semverLT(a, b) {
|
|
1087
|
+
const pa = a.split(".").map(Number);
|
|
1088
|
+
const pb = b.split(".").map(Number);
|
|
1089
|
+
for (let i = 0; i < 3; i++) {
|
|
1090
|
+
if ((pa[i] ?? 0) < (pb[i] ?? 0)) return true;
|
|
1091
|
+
if ((pa[i] ?? 0) > (pb[i] ?? 0)) return false;
|
|
1092
|
+
}
|
|
1093
|
+
return false;
|
|
1094
|
+
}
|
|
1095
|
+
function currentVersion() {
|
|
1096
|
+
return true ? "0.2.1" : "0.0.0";
|
|
1097
|
+
}
|
|
1098
|
+
function toUpdateStatus(latestVersion, checkedAt) {
|
|
1099
|
+
const current = currentVersion();
|
|
1100
|
+
return {
|
|
1101
|
+
currentVersion: current,
|
|
1102
|
+
latestVersion,
|
|
1103
|
+
updateAvailable: latestVersion ? semverLT(current, latestVersion) : false,
|
|
1104
|
+
installCommand: UPDATE_INSTALL_COMMAND,
|
|
1105
|
+
checkedAt
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
function getUpdateStatus() {
|
|
1109
|
+
const cache = readCache();
|
|
1110
|
+
if (cache && Date.now() - cache.checkedAt < CACHE_TTL_MS) {
|
|
1111
|
+
return toUpdateStatus(cache.latest, cache.checkedAt);
|
|
1112
|
+
}
|
|
1113
|
+
const latest = fetchLatestVersion();
|
|
1114
|
+
if (latest) {
|
|
1115
|
+
const checkedAt = Date.now();
|
|
1116
|
+
writeCache({ latest, checkedAt });
|
|
1117
|
+
return toUpdateStatus(latest, checkedAt);
|
|
1118
|
+
}
|
|
1119
|
+
if (cache) {
|
|
1120
|
+
return toUpdateStatus(cache.latest, cache.checkedAt);
|
|
1121
|
+
}
|
|
1122
|
+
return toUpdateStatus(null, null);
|
|
1123
|
+
}
|
|
1124
|
+
function getAvailableUpdate() {
|
|
1125
|
+
const current = currentVersion();
|
|
1126
|
+
const cache = readCache();
|
|
1127
|
+
if (cache && Date.now() - cache.checkedAt < CACHE_TTL_MS) {
|
|
1128
|
+
return semverLT(current, cache.latest) ? cache.latest : null;
|
|
1129
|
+
}
|
|
1130
|
+
const latest = fetchLatestVersion();
|
|
1131
|
+
if (latest) {
|
|
1132
|
+
writeCache({ latest, checkedAt: Date.now() });
|
|
1133
|
+
return semverLT(current, latest) ? latest : null;
|
|
1134
|
+
}
|
|
1135
|
+
return null;
|
|
1136
|
+
}
|
|
1137
|
+
function getUpdateNoticeLines(latest) {
|
|
1138
|
+
const yellow2 = esc("33");
|
|
1139
|
+
const bold2 = esc("1");
|
|
1140
|
+
const dim2 = esc("2");
|
|
1141
|
+
return [
|
|
1142
|
+
` ${yellow2("Update available")} ${dim2(currentVersion())} \u2192 ${bold2(latest)}`,
|
|
1143
|
+
` Run ${bold2(UPDATE_INSTALL_COMMAND)} to update`
|
|
1144
|
+
];
|
|
1145
|
+
}
|
|
1146
|
+
function printUpdateNotice(latest) {
|
|
1147
|
+
process.stderr.write(`
|
|
1148
|
+
${getUpdateNoticeLines(latest).join("\n")}
|
|
1149
|
+
|
|
1150
|
+
`);
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1050
1153
|
export {
|
|
1051
1154
|
noColor,
|
|
1052
1155
|
identity,
|
|
@@ -1110,5 +1213,9 @@ export {
|
|
|
1110
1213
|
timeAgo,
|
|
1111
1214
|
etherscanTxURL,
|
|
1112
1215
|
brandedHelp,
|
|
1113
|
-
isInteractiveAllowed
|
|
1216
|
+
isInteractiveAllowed,
|
|
1217
|
+
getUpdateStatus,
|
|
1218
|
+
getAvailableUpdate,
|
|
1219
|
+
getUpdateNoticeLines,
|
|
1220
|
+
printUpdateNotice
|
|
1114
1221
|
};
|
package/dist/index.js
CHANGED
|
@@ -14,13 +14,13 @@ import {
|
|
|
14
14
|
splitCommaList,
|
|
15
15
|
validateAddress,
|
|
16
16
|
validateTxHash
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-XP5KF4W2.js";
|
|
18
18
|
import {
|
|
19
19
|
getRPCNetworks,
|
|
20
20
|
getSetupStatus,
|
|
21
21
|
isSetupComplete,
|
|
22
22
|
shouldRunOnboarding
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-HBRTTBCY.js";
|
|
24
24
|
import {
|
|
25
25
|
EXIT_CODES,
|
|
26
26
|
ErrorCode,
|
|
@@ -42,6 +42,8 @@ import {
|
|
|
42
42
|
exitWithError,
|
|
43
43
|
failBadge,
|
|
44
44
|
formatCommanderError,
|
|
45
|
+
getAvailableUpdate,
|
|
46
|
+
getUpdateStatus,
|
|
45
47
|
green,
|
|
46
48
|
identity,
|
|
47
49
|
isInteractiveAllowed,
|
|
@@ -54,6 +56,7 @@ import {
|
|
|
54
56
|
printKeyValueBox,
|
|
55
57
|
printSyntaxJSON,
|
|
56
58
|
printTable,
|
|
59
|
+
printUpdateNotice,
|
|
57
60
|
promptSelect,
|
|
58
61
|
quiet,
|
|
59
62
|
setFlags,
|
|
@@ -62,7 +65,7 @@ import {
|
|
|
62
65
|
verbose,
|
|
63
66
|
weiToEth,
|
|
64
67
|
withSpinner
|
|
65
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-SDUCDSCZ.js";
|
|
66
69
|
|
|
67
70
|
// src/index.ts
|
|
68
71
|
import { Command, Help } from "commander";
|
|
@@ -1678,7 +1681,8 @@ function buildAgentPrompt(program2) {
|
|
|
1678
1681
|
"Always pass --json --no-interactive",
|
|
1679
1682
|
"Parse stdout as JSON on exit code 0",
|
|
1680
1683
|
"Parse stderr as JSON on nonzero exit code",
|
|
1681
|
-
"Never run bare 'alchemy' without --json --no-interactive"
|
|
1684
|
+
"Never run bare 'alchemy' without --json --no-interactive",
|
|
1685
|
+
"Run alchemy --json --no-interactive update-check when you need to detect available CLI upgrades"
|
|
1682
1686
|
],
|
|
1683
1687
|
preflight: {
|
|
1684
1688
|
command: "alchemy --json setup status",
|
|
@@ -1742,6 +1746,7 @@ function buildAgentPrompt(program2) {
|
|
|
1742
1746
|
errors,
|
|
1743
1747
|
examples: [
|
|
1744
1748
|
"alchemy --json --no-interactive setup status",
|
|
1749
|
+
"alchemy --json --no-interactive update-check",
|
|
1745
1750
|
"alchemy --json --no-interactive balance 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --api-key $ALCHEMY_API_KEY",
|
|
1746
1751
|
"alchemy --json --no-interactive apps list --access-key $ALCHEMY_ACCESS_KEY",
|
|
1747
1752
|
"alchemy --json --no-interactive rpc eth_blockNumber --api-key $ALCHEMY_API_KEY",
|
|
@@ -1800,6 +1805,27 @@ function registerAgentPrompt(program2) {
|
|
|
1800
1805
|
});
|
|
1801
1806
|
}
|
|
1802
1807
|
|
|
1808
|
+
// src/commands/update-check.ts
|
|
1809
|
+
function formatCheckedAt(checkedAt) {
|
|
1810
|
+
return checkedAt ? new Date(checkedAt).toISOString() : dim("(unknown)");
|
|
1811
|
+
}
|
|
1812
|
+
function registerUpdateCheck(program2) {
|
|
1813
|
+
program2.command("update-check").description("Check whether a newer CLI version is available").action(() => {
|
|
1814
|
+
const status = getUpdateStatus();
|
|
1815
|
+
if (isJSONMode()) {
|
|
1816
|
+
printJSON(status);
|
|
1817
|
+
return;
|
|
1818
|
+
}
|
|
1819
|
+
printKeyValueBox([
|
|
1820
|
+
["Current version", status.currentVersion],
|
|
1821
|
+
["Latest version", status.latestVersion ?? dim("(unknown)")],
|
|
1822
|
+
["Update available", status.updateAvailable ? "yes" : "no"],
|
|
1823
|
+
["Checked at", formatCheckedAt(status.checkedAt)],
|
|
1824
|
+
["Install", status.installCommand]
|
|
1825
|
+
]);
|
|
1826
|
+
});
|
|
1827
|
+
}
|
|
1828
|
+
|
|
1803
1829
|
// src/index.ts
|
|
1804
1830
|
var hBrand = noColor ? identity : (s) => `\x1B[38;2;54;63;249m${s}\x1B[39m`;
|
|
1805
1831
|
var hBold = esc("1");
|
|
@@ -1837,7 +1863,7 @@ var ROOT_COMMAND_PILLARS = [
|
|
|
1837
1863
|
},
|
|
1838
1864
|
{
|
|
1839
1865
|
label: "Admin",
|
|
1840
|
-
commands: ["apps", "config", "setup", "agent-prompt", "version", "help"]
|
|
1866
|
+
commands: ["apps", "config", "setup", "agent-prompt", "update-check", "version", "help"]
|
|
1841
1867
|
}
|
|
1842
1868
|
];
|
|
1843
1869
|
function formatCommandSignature(sub) {
|
|
@@ -1872,12 +1898,29 @@ var findCommandByPath = (root, path) => {
|
|
|
1872
1898
|
}
|
|
1873
1899
|
return current;
|
|
1874
1900
|
};
|
|
1901
|
+
var cachedAvailableUpdate;
|
|
1902
|
+
var updateShownDuringInteractiveStartup = false;
|
|
1903
|
+
function getAvailableUpdateOnce() {
|
|
1904
|
+
if (cachedAvailableUpdate === void 0) {
|
|
1905
|
+
cachedAvailableUpdate = getAvailableUpdate();
|
|
1906
|
+
}
|
|
1907
|
+
return cachedAvailableUpdate;
|
|
1908
|
+
}
|
|
1909
|
+
function resetUpdateNoticeState() {
|
|
1910
|
+
cachedAvailableUpdate = void 0;
|
|
1911
|
+
updateShownDuringInteractiveStartup = false;
|
|
1912
|
+
}
|
|
1875
1913
|
program.name("alchemy").description(
|
|
1876
1914
|
"The Alchemy CLI lets you query blockchain data, call JSON-RPC methods, and manage your Alchemy configuration."
|
|
1877
|
-
).version("0.2.
|
|
1915
|
+
).version("0.2.1", "-v, --version", "display CLI version").option("--api-key <key>", "Alchemy API key (env: ALCHEMY_API_KEY)").option("--access-key <key>", "Alchemy access key (env: ALCHEMY_ACCESS_KEY)").option(
|
|
1878
1916
|
"-n, --network <network>",
|
|
1879
1917
|
"Target network (default: eth-mainnet) (env: ALCHEMY_NETWORK)"
|
|
1880
|
-
).option("--x402", "Use x402 wallet-based gateway auth").option("--wallet-key-file <path>", "Path to wallet private key file for x402").option("--json", "Force JSON output").option("-q, --quiet", "Suppress non-essential output").option("
|
|
1918
|
+
).option("--x402", "Use x402 wallet-based gateway auth").option("--wallet-key-file <path>", "Path to wallet private key file for x402").option("--json", "Force JSON output").option("-q, --quiet", "Suppress non-essential output").option("--verbose", "Enable verbose output").option("--no-color", "Disable color output").option("--reveal", "Show secrets in plain text (TTY only)").option("--timeout <ms>", "Request timeout in milliseconds", parseInt).option("--debug", "Enable debug diagnostics").option("--no-interactive", "Disable REPL and prompt-driven interactions").addHelpCommand(false).exitOverride((err) => {
|
|
1919
|
+
if (err.code === "commander.help" || err.code === "commander.helpDisplayed" || err.code === "commander.version") {
|
|
1920
|
+
process.exit(0);
|
|
1921
|
+
}
|
|
1922
|
+
process.exit(EXIT_CODES.INVALID_ARGS);
|
|
1923
|
+
}).configureOutput({
|
|
1881
1924
|
outputError(str, write) {
|
|
1882
1925
|
write(formatCommanderError(str));
|
|
1883
1926
|
}
|
|
@@ -2018,27 +2061,39 @@ ${styledLine}`;
|
|
|
2018
2061
|
}).hook("postAction", () => {
|
|
2019
2062
|
if (!isJSONMode() && !quiet) {
|
|
2020
2063
|
console.log("");
|
|
2064
|
+
if (!updateShownDuringInteractiveStartup) {
|
|
2065
|
+
const latest = getAvailableUpdateOnce();
|
|
2066
|
+
if (latest) printUpdateNotice(latest);
|
|
2067
|
+
}
|
|
2021
2068
|
}
|
|
2069
|
+
resetUpdateNoticeState();
|
|
2022
2070
|
}).action(async () => {
|
|
2023
2071
|
const cfg = load();
|
|
2024
2072
|
if (!isSetupComplete(cfg) && !isInteractiveAllowed(program)) {
|
|
2025
2073
|
throw errSetupRequired(getSetupStatus(cfg));
|
|
2026
2074
|
}
|
|
2027
2075
|
if (isInteractiveAllowed(program)) {
|
|
2076
|
+
let latestForInteractiveStartup = null;
|
|
2028
2077
|
if (shouldRunOnboarding(program, cfg)) {
|
|
2029
|
-
const { runOnboarding } = await import("./onboarding-
|
|
2030
|
-
const
|
|
2078
|
+
const { runOnboarding } = await import("./onboarding-YA32OJOT.js");
|
|
2079
|
+
const latest = getAvailableUpdateOnce();
|
|
2080
|
+
const completed = await runOnboarding(program, latest);
|
|
2081
|
+
updateShownDuringInteractiveStartup = Boolean(latest);
|
|
2082
|
+
latestForInteractiveStartup = null;
|
|
2031
2083
|
if (!completed) {
|
|
2032
2084
|
return;
|
|
2033
2085
|
}
|
|
2086
|
+
} else {
|
|
2087
|
+
latestForInteractiveStartup = getAvailableUpdateOnce();
|
|
2088
|
+
updateShownDuringInteractiveStartup = Boolean(latestForInteractiveStartup);
|
|
2034
2089
|
}
|
|
2035
|
-
const { startREPL } = await import("./interactive-
|
|
2090
|
+
const { startREPL } = await import("./interactive-L7N4HI7K.js");
|
|
2036
2091
|
program.exitOverride();
|
|
2037
2092
|
program.configureOutput({
|
|
2038
2093
|
writeErr: () => {
|
|
2039
2094
|
}
|
|
2040
2095
|
});
|
|
2041
|
-
await startREPL(program);
|
|
2096
|
+
await startREPL(program, latestForInteractiveStartup);
|
|
2042
2097
|
return;
|
|
2043
2098
|
}
|
|
2044
2099
|
program.help();
|
|
@@ -2066,6 +2121,7 @@ registerSetup(program);
|
|
|
2066
2121
|
registerConfig(program);
|
|
2067
2122
|
registerSolana(program);
|
|
2068
2123
|
registerAgentPrompt(program);
|
|
2124
|
+
registerUpdateCheck(program);
|
|
2069
2125
|
registerVersion(program);
|
|
2070
2126
|
program.command("help [command...]").description("display help for command").action((commandPath) => {
|
|
2071
2127
|
if (!commandPath || commandPath.length === 0) {
|
|
@@ -3,7 +3,7 @@ if(process.argv.includes("--no-color"))process.env.NO_COLOR="1";
|
|
|
3
3
|
import {
|
|
4
4
|
getRPCNetworkIds,
|
|
5
5
|
getSetupMethod
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-HBRTTBCY.js";
|
|
7
7
|
import {
|
|
8
8
|
bgRgb,
|
|
9
9
|
bold,
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
brandedHelp,
|
|
12
12
|
configDir,
|
|
13
13
|
dim,
|
|
14
|
+
getUpdateNoticeLines,
|
|
14
15
|
green,
|
|
15
16
|
isJSONMode,
|
|
16
17
|
load,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
rgb,
|
|
19
20
|
setBrandedHelpSuppressed,
|
|
20
21
|
setReplMode
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-SDUCDSCZ.js";
|
|
22
23
|
|
|
23
24
|
// src/commands/interactive.ts
|
|
24
25
|
import * as readline from "readline";
|
|
@@ -88,6 +89,7 @@ var COMMAND_NAMES = [
|
|
|
88
89
|
"config get",
|
|
89
90
|
"config list",
|
|
90
91
|
"help",
|
|
92
|
+
"update-check",
|
|
91
93
|
"network",
|
|
92
94
|
"network list",
|
|
93
95
|
"nfts",
|
|
@@ -136,7 +138,7 @@ function saveReplHistory(lines) {
|
|
|
136
138
|
mkdirSync(dirname(historyFilePath), { recursive: true, mode: 493 });
|
|
137
139
|
writeFileSync(historyFilePath, normalized.join("\n") + "\n", { mode: 384 });
|
|
138
140
|
}
|
|
139
|
-
async function startREPL(program) {
|
|
141
|
+
async function startREPL(program, latestUpdate = null) {
|
|
140
142
|
if (!stdin.isTTY) return;
|
|
141
143
|
setReplMode(true);
|
|
142
144
|
setBrandedHelpSuppressed(true);
|
|
@@ -217,6 +219,12 @@ async function startREPL(program) {
|
|
|
217
219
|
console.log(` ${green("\u2713")} ${dim(`Configured auth: ${formatSetupMethodLabel()}`)}`);
|
|
218
220
|
console.log(` ${dim("Run commands directly (no 'alchemy' prefix).")}`);
|
|
219
221
|
console.log("");
|
|
222
|
+
if (latestUpdate) {
|
|
223
|
+
for (const line of getUpdateNoticeLines(latestUpdate)) {
|
|
224
|
+
console.log(line);
|
|
225
|
+
}
|
|
226
|
+
console.log("");
|
|
227
|
+
}
|
|
220
228
|
console.log(` ${brand("\u25C6")} ${bold("Quick commands")}`);
|
|
221
229
|
console.log(` ${dim("- rpc eth_chainId")}`);
|
|
222
230
|
console.log(` ${dim("- config list")}`);
|
|
@@ -5,12 +5,13 @@ import {
|
|
|
5
5
|
generateAndPersistWallet,
|
|
6
6
|
importAndPersistWallet,
|
|
7
7
|
selectOrCreateApp
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-XP5KF4W2.js";
|
|
9
9
|
import {
|
|
10
10
|
bold,
|
|
11
11
|
brand,
|
|
12
12
|
brandedHelp,
|
|
13
13
|
dim,
|
|
14
|
+
getUpdateNoticeLines,
|
|
14
15
|
green,
|
|
15
16
|
load,
|
|
16
17
|
maskIf,
|
|
@@ -18,7 +19,7 @@ import {
|
|
|
18
19
|
promptSelect,
|
|
19
20
|
promptText,
|
|
20
21
|
save
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-SDUCDSCZ.js";
|
|
22
23
|
|
|
23
24
|
// src/commands/onboarding.ts
|
|
24
25
|
function printNextSteps(method) {
|
|
@@ -106,7 +107,7 @@ async function runX402Onboarding() {
|
|
|
106
107
|
save({ ...cfg, x402: true });
|
|
107
108
|
console.log(` ${green("\u2713")} x402 enabled with wallet ${wallet.address}`);
|
|
108
109
|
}
|
|
109
|
-
async function runOnboarding(_program) {
|
|
110
|
+
async function runOnboarding(_program, latestUpdate = null) {
|
|
110
111
|
process.stdout.write(brandedHelp({ force: true }));
|
|
111
112
|
console.log("");
|
|
112
113
|
console.log(` ${brand("\u25C6")} ${bold("Welcome to Alchemy CLI")}`);
|
|
@@ -115,6 +116,12 @@ async function runOnboarding(_program) {
|
|
|
115
116
|
console.log(` ${dim(" Choose one auth path to continue.")}`);
|
|
116
117
|
console.log(` ${dim(" Tip: select 'exit' to skip setup for now.")}`);
|
|
117
118
|
console.log("");
|
|
119
|
+
if (latestUpdate) {
|
|
120
|
+
for (const line of getUpdateNoticeLines(latestUpdate)) {
|
|
121
|
+
console.log(line);
|
|
122
|
+
}
|
|
123
|
+
console.log("");
|
|
124
|
+
}
|
|
118
125
|
const method = await promptSelect({
|
|
119
126
|
message: "Choose an auth setup path",
|
|
120
127
|
options: [
|