settld 0.2.1 → 0.2.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 +32 -0
- package/bin/settld.js +13 -0
- package/docs/QUICKSTART_MCP_HOSTS.md +90 -11
- package/docs/README.md +5 -4
- package/docs/gitbook/README.md +5 -1
- package/docs/gitbook/quickstart.md +58 -8
- package/docs/integrations/README.md +1 -1
- package/docs/integrations/openclaw/CLAWHUB_PUBLISH_CHECKLIST.md +1 -1
- package/docs/integrations/openclaw/PUBLIC_QUICKSTART.md +7 -5
- package/docs/integrations/openclaw/settld-mcp-skill/SKILL.md +19 -4
- package/docs/integrations/openclaw/settld-mcp-skill/mcp-server.example.json +3 -5
- package/docs/integrations/openclaw/settld-mcp-skill/skill.json +11 -0
- package/package.json +2 -1
- package/scripts/ci/run-mcp-host-smoke.mjs +6 -0
- package/scripts/ci/run-production-cutover-gate.mjs +6 -0
- package/scripts/demo/mcp-paid-exa.mjs +18 -1
- package/scripts/setup/login.mjs +5 -2
- package/scripts/setup/onboard.mjs +337 -58
- package/scripts/vercel/build-mkdocs.sh +3 -3
- package/scripts/vercel/ignore-dashboard.sh +3 -0
- package/scripts/vercel/install-mkdocs.sh +2 -3
- package/scripts/wallet/cli.mjs +871 -0
- package/src/core/wallet-funding-coinbase.js +197 -0
- package/src/core/wallet-funding-hosted.js +155 -0
- package/src/core/wallet-provider-bootstrap.js +95 -0
|
@@ -13,10 +13,13 @@ import { bootstrapWalletProvider } from "../../src/core/wallet-provider-bootstra
|
|
|
13
13
|
import { extractBootstrapMcpEnv, loadHostConfigHelper, runWizard } from "./wizard.mjs";
|
|
14
14
|
import { SUPPORTED_HOSTS } from "./host-config.mjs";
|
|
15
15
|
import { defaultSessionPath, readSavedSession } from "./session-store.mjs";
|
|
16
|
+
import { runLogin } from "./login.mjs";
|
|
17
|
+
import { runWalletCli } from "../wallet/cli.mjs";
|
|
16
18
|
|
|
17
19
|
const WALLET_MODES = new Set(["managed", "byo", "none"]);
|
|
18
20
|
const WALLET_PROVIDERS = new Set(["circle"]);
|
|
19
21
|
const WALLET_BOOTSTRAP_MODES = new Set(["auto", "local", "remote"]);
|
|
22
|
+
const SETUP_MODES = new Set(["quick", "advanced"]);
|
|
20
23
|
const FORMAT_OPTIONS = new Set(["text", "json"]);
|
|
21
24
|
const HOST_BINARY_HINTS = Object.freeze({
|
|
22
25
|
codex: "codex",
|
|
@@ -38,6 +41,7 @@ const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
|
|
|
38
41
|
const REPO_ROOT = path.resolve(SCRIPT_DIR, "..", "..");
|
|
39
42
|
const SETTLD_BIN = path.join(REPO_ROOT, "bin", "settld.js");
|
|
40
43
|
const PROFILE_FINGERPRINT_REGEX = /^[0-9a-f]{64}$/;
|
|
44
|
+
const DEFAULT_PUBLIC_BASE_URL = "https://api.settld.work";
|
|
41
45
|
const ANSI_RESET = "\u001b[0m";
|
|
42
46
|
const ANSI_BOLD = "\u001b[1m";
|
|
43
47
|
const ANSI_DIM = "\u001b[2m";
|
|
@@ -54,6 +58,10 @@ function usage() {
|
|
|
54
58
|
"",
|
|
55
59
|
"flags:",
|
|
56
60
|
" --non-interactive Disable prompts; require explicit flags",
|
|
61
|
+
" --quick Quick setup mode (default for interactive)",
|
|
62
|
+
" --advanced Advanced setup mode (shows all prompts)",
|
|
63
|
+
" --guided-next Run guided fund + first paid check after setup (default in quick mode)",
|
|
64
|
+
" --skip-guided-next Skip guided post-setup actions",
|
|
57
65
|
` --host <${SUPPORTED_HOSTS.join("|")}> Host target (default: auto-detect, fallback openclaw)`,
|
|
58
66
|
" --base-url <url> Settld API base URL (or SETTLD_BASE_URL)",
|
|
59
67
|
" --tenant-id <id> Settld tenant ID (or SETTLD_TENANT_ID)",
|
|
@@ -109,6 +117,8 @@ function parseWalletEnvAssignment(raw) {
|
|
|
109
117
|
function parseArgs(argv) {
|
|
110
118
|
const out = {
|
|
111
119
|
nonInteractive: false,
|
|
120
|
+
setupMode: null,
|
|
121
|
+
guidedNext: null,
|
|
112
122
|
host: null,
|
|
113
123
|
baseUrl: null,
|
|
114
124
|
tenantId: null,
|
|
@@ -149,6 +159,22 @@ function parseArgs(argv) {
|
|
|
149
159
|
out.nonInteractive = true;
|
|
150
160
|
continue;
|
|
151
161
|
}
|
|
162
|
+
if (arg === "--quick") {
|
|
163
|
+
out.setupMode = "quick";
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (arg === "--advanced") {
|
|
167
|
+
out.setupMode = "advanced";
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
if (arg === "--guided-next") {
|
|
171
|
+
out.guidedNext = true;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (arg === "--skip-guided-next") {
|
|
175
|
+
out.guidedNext = false;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
152
178
|
if (arg === "--skip-profile-apply") {
|
|
153
179
|
out.skipProfileApply = true;
|
|
154
180
|
continue;
|
|
@@ -310,6 +336,9 @@ function parseArgs(argv) {
|
|
|
310
336
|
if (out.host && !SUPPORTED_HOSTS.includes(out.host)) {
|
|
311
337
|
throw new Error(`--host must be one of: ${SUPPORTED_HOSTS.join(", ")}`);
|
|
312
338
|
}
|
|
339
|
+
if (out.setupMode && !SETUP_MODES.has(out.setupMode)) {
|
|
340
|
+
throw new Error("--quick or --advanced are the supported setup modes");
|
|
341
|
+
}
|
|
313
342
|
if (!WALLET_MODES.has(out.walletMode)) throw new Error("--wallet-mode must be managed|byo|none");
|
|
314
343
|
if (!WALLET_PROVIDERS.has(out.walletProvider)) throw new Error(`--wallet-provider must be one of: ${[...WALLET_PROVIDERS].join(", ")}`);
|
|
315
344
|
if (!WALLET_BOOTSTRAP_MODES.has(out.walletBootstrap)) throw new Error("--wallet-bootstrap must be auto|local|remote");
|
|
@@ -865,6 +894,144 @@ function buildHostNextSteps({ host, installedHosts }) {
|
|
|
865
894
|
return steps;
|
|
866
895
|
}
|
|
867
896
|
|
|
897
|
+
function runMcpPaidCallProbe({ env, timeoutMs = 45_000 } = {}) {
|
|
898
|
+
const args = [
|
|
899
|
+
path.join("scripts", "mcp", "probe.mjs"),
|
|
900
|
+
"--call",
|
|
901
|
+
"settld.weather_current_paid",
|
|
902
|
+
JSON.stringify({ city: "Chicago", unit: "f" }),
|
|
903
|
+
"--timeout-ms",
|
|
904
|
+
String(timeoutMs)
|
|
905
|
+
];
|
|
906
|
+
const result = spawnSync(process.execPath, args, {
|
|
907
|
+
cwd: REPO_ROOT,
|
|
908
|
+
env: { ...process.env, ...(env ?? {}) },
|
|
909
|
+
encoding: "utf8",
|
|
910
|
+
timeout: timeoutMs + 5000,
|
|
911
|
+
maxBuffer: 4 * 1024 * 1024,
|
|
912
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
913
|
+
});
|
|
914
|
+
const stdoutText = String(result.stdout ?? "");
|
|
915
|
+
const stderrText = String(result.stderr ?? "");
|
|
916
|
+
const sawToolError = /"isError"\s*:\s*true/.test(stdoutText);
|
|
917
|
+
const sawToolSuccess = /"isError"\s*:\s*false/.test(stdoutText);
|
|
918
|
+
const ok = Number(result.status) === 0 && sawToolSuccess && !sawToolError;
|
|
919
|
+
return {
|
|
920
|
+
ok,
|
|
921
|
+
exitCode: typeof result.status === "number" ? result.status : 1,
|
|
922
|
+
stdout: stdoutText,
|
|
923
|
+
stderr: stderrText
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
async function runGuidedQuickFlow({
|
|
928
|
+
enabled = false,
|
|
929
|
+
walletMode = "none",
|
|
930
|
+
normalizedBaseUrl,
|
|
931
|
+
tenantId,
|
|
932
|
+
sessionFile,
|
|
933
|
+
sessionCookie = "",
|
|
934
|
+
mergedEnv = {},
|
|
935
|
+
runtimeEnv = process.env,
|
|
936
|
+
stdin = process.stdin,
|
|
937
|
+
stdout = process.stdout,
|
|
938
|
+
runWalletCliImpl = runWalletCli
|
|
939
|
+
} = {}) {
|
|
940
|
+
const summary = {
|
|
941
|
+
enabled: Boolean(enabled),
|
|
942
|
+
ran: false,
|
|
943
|
+
walletFund: null,
|
|
944
|
+
walletBalanceWatch: null,
|
|
945
|
+
firstPaidCall: null,
|
|
946
|
+
warnings: []
|
|
947
|
+
};
|
|
948
|
+
if (!summary.enabled) return summary;
|
|
949
|
+
if (!stdin?.isTTY || !stdout?.isTTY) {
|
|
950
|
+
summary.warnings.push("guided quick flow skipped (non-interactive terminal)");
|
|
951
|
+
return summary;
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
const actionEnv = {
|
|
955
|
+
...runtimeEnv,
|
|
956
|
+
...mergedEnv,
|
|
957
|
+
SETTLD_BASE_URL: normalizedBaseUrl,
|
|
958
|
+
SETTLD_TENANT_ID: tenantId,
|
|
959
|
+
...(sessionCookie ? { SETTLD_SESSION_COOKIE: sessionCookie } : {})
|
|
960
|
+
};
|
|
961
|
+
summary.ran = true;
|
|
962
|
+
|
|
963
|
+
if (walletMode !== "none") {
|
|
964
|
+
try {
|
|
965
|
+
const fundResult = await runWalletCliImpl({
|
|
966
|
+
argv: ["fund", "--open", "--base-url", normalizedBaseUrl, "--tenant-id", tenantId, "--session-file", sessionFile, "--format", "json"],
|
|
967
|
+
env: actionEnv,
|
|
968
|
+
stdin,
|
|
969
|
+
stdout
|
|
970
|
+
});
|
|
971
|
+
summary.walletFund = {
|
|
972
|
+
ok: true,
|
|
973
|
+
method: String(fundResult?.method ?? "").trim() || null
|
|
974
|
+
};
|
|
975
|
+
} catch (err) {
|
|
976
|
+
summary.walletFund = {
|
|
977
|
+
ok: false,
|
|
978
|
+
error: err?.message ?? String(err ?? "")
|
|
979
|
+
};
|
|
980
|
+
summary.warnings.push("wallet funding did not complete during guided flow");
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
try {
|
|
984
|
+
const watchResult = await runWalletCliImpl({
|
|
985
|
+
argv: [
|
|
986
|
+
"balance",
|
|
987
|
+
"--watch",
|
|
988
|
+
"--min-usdc",
|
|
989
|
+
"1",
|
|
990
|
+
"--timeout-seconds",
|
|
991
|
+
"300",
|
|
992
|
+
"--interval-seconds",
|
|
993
|
+
"5",
|
|
994
|
+
"--base-url",
|
|
995
|
+
normalizedBaseUrl,
|
|
996
|
+
"--tenant-id",
|
|
997
|
+
tenantId,
|
|
998
|
+
"--session-file",
|
|
999
|
+
sessionFile,
|
|
1000
|
+
"--format",
|
|
1001
|
+
"json"
|
|
1002
|
+
],
|
|
1003
|
+
env: actionEnv,
|
|
1004
|
+
stdin,
|
|
1005
|
+
stdout
|
|
1006
|
+
});
|
|
1007
|
+
summary.walletBalanceWatch = {
|
|
1008
|
+
ok: Boolean(watchResult?.ok),
|
|
1009
|
+
satisfied: Boolean(watchResult?.watch?.satisfied)
|
|
1010
|
+
};
|
|
1011
|
+
} catch (err) {
|
|
1012
|
+
summary.walletBalanceWatch = {
|
|
1013
|
+
ok: false,
|
|
1014
|
+
error: err?.message ?? String(err ?? "")
|
|
1015
|
+
};
|
|
1016
|
+
summary.warnings.push("wallet balance watch did not reach target within timeout");
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
const paidProbe = runMcpPaidCallProbe({ env: actionEnv });
|
|
1021
|
+
if (paidProbe.ok) {
|
|
1022
|
+
summary.firstPaidCall = { ok: true };
|
|
1023
|
+
} else {
|
|
1024
|
+
summary.firstPaidCall = {
|
|
1025
|
+
ok: false,
|
|
1026
|
+
exitCode: paidProbe.exitCode,
|
|
1027
|
+
error: paidProbe.stderr || "paid call returned tool error"
|
|
1028
|
+
};
|
|
1029
|
+
summary.warnings.push("first paid call probe failed");
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1032
|
+
return summary;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
868
1035
|
function resolveByoWalletEnv({ walletProvider, walletEnvRows, runtimeEnv }) {
|
|
869
1036
|
const env = {};
|
|
870
1037
|
for (const row of walletEnvRows ?? []) env[row.key] = row.value;
|
|
@@ -1028,16 +1195,21 @@ async function resolveRuntimeConfig({
|
|
|
1028
1195
|
runtimeEnv,
|
|
1029
1196
|
stdin = process.stdin,
|
|
1030
1197
|
stdout = process.stdout,
|
|
1031
|
-
detectInstalledHostsImpl = detectInstalledHosts
|
|
1198
|
+
detectInstalledHostsImpl = detectInstalledHosts,
|
|
1199
|
+
fetchImpl = fetch,
|
|
1200
|
+
runLoginImpl = runLogin,
|
|
1201
|
+
readSavedSessionImpl = readSavedSession
|
|
1032
1202
|
}) {
|
|
1033
1203
|
const sessionFile = String(args.sessionFile ?? runtimeEnv.SETTLD_SESSION_FILE ?? defaultSessionPath()).trim();
|
|
1034
|
-
const savedSession = await
|
|
1204
|
+
const savedSession = await readSavedSessionImpl({ sessionPath: sessionFile });
|
|
1035
1205
|
const installedHosts = detectInstalledHostsImpl();
|
|
1036
1206
|
const defaultHost = selectDefaultHost({
|
|
1037
1207
|
explicitHost: args.host ? String(args.host).toLowerCase() : "",
|
|
1038
1208
|
installedHosts
|
|
1039
1209
|
});
|
|
1040
1210
|
const out = {
|
|
1211
|
+
setupMode: args.setupMode ?? "quick",
|
|
1212
|
+
guidedNext: args.guidedNext,
|
|
1041
1213
|
host: args.host ?? defaultHost,
|
|
1042
1214
|
walletMode: args.walletMode,
|
|
1043
1215
|
baseUrl: String(args.baseUrl ?? runtimeEnv.SETTLD_BASE_URL ?? "").trim(),
|
|
@@ -1071,6 +1243,9 @@ async function resolveRuntimeConfig({
|
|
|
1071
1243
|
}
|
|
1072
1244
|
|
|
1073
1245
|
if (args.nonInteractive) {
|
|
1246
|
+
if (!out.setupMode) out.setupMode = "quick";
|
|
1247
|
+
if (!SETUP_MODES.has(out.setupMode)) throw new Error("--quick or --advanced are the supported setup modes");
|
|
1248
|
+
if (out.guidedNext === null || out.guidedNext === undefined) out.guidedNext = false;
|
|
1074
1249
|
if (!SUPPORTED_HOSTS.includes(out.host)) throw new Error(`--host must be one of: ${SUPPORTED_HOSTS.join(", ")}`);
|
|
1075
1250
|
if (!out.baseUrl) throw new Error("--base-url is required");
|
|
1076
1251
|
if (!out.tenantId) throw new Error("--tenant-id is required");
|
|
@@ -1105,6 +1280,24 @@ async function resolveRuntimeConfig({
|
|
|
1105
1280
|
}
|
|
1106
1281
|
stdout.write("\n");
|
|
1107
1282
|
|
|
1283
|
+
if (!out.setupMode || !SETUP_MODES.has(out.setupMode)) {
|
|
1284
|
+
out.setupMode = "quick";
|
|
1285
|
+
}
|
|
1286
|
+
out.setupMode = await promptSelect(
|
|
1287
|
+
rl,
|
|
1288
|
+
stdin,
|
|
1289
|
+
stdout,
|
|
1290
|
+
"Setup mode",
|
|
1291
|
+
[
|
|
1292
|
+
{ value: "quick", label: "quick", hint: "Recommended: minimal prompts and guided next steps" },
|
|
1293
|
+
{ value: "advanced", label: "advanced", hint: "Full control over all setup options" }
|
|
1294
|
+
],
|
|
1295
|
+
{ defaultValue: out.setupMode, color }
|
|
1296
|
+
);
|
|
1297
|
+
if (out.guidedNext === null || out.guidedNext === undefined) {
|
|
1298
|
+
out.guidedNext = out.setupMode === "quick";
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1108
1301
|
const hostPromptDefault = out.host && SUPPORTED_HOSTS.includes(out.host) ? out.host : defaultHost;
|
|
1109
1302
|
const hostOptions = SUPPORTED_HOSTS.map((host) => ({
|
|
1110
1303
|
value: host,
|
|
@@ -1133,68 +1326,100 @@ async function resolveRuntimeConfig({
|
|
|
1133
1326
|
{ defaultValue: out.walletMode, color }
|
|
1134
1327
|
);
|
|
1135
1328
|
|
|
1136
|
-
if (!out.baseUrl)
|
|
1137
|
-
out.baseUrl = await promptLine(rl, "Settld base URL", { defaultValue: "https://api.settld.work" });
|
|
1138
|
-
}
|
|
1139
|
-
if (!out.tenantId) {
|
|
1140
|
-
out.tenantId = await promptLine(rl, "Tenant ID", { defaultValue: "tenant_default" });
|
|
1141
|
-
}
|
|
1329
|
+
if (!out.baseUrl) out.baseUrl = DEFAULT_PUBLIC_BASE_URL;
|
|
1142
1330
|
if (!out.settldApiKey) {
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
(
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1331
|
+
while (!out.settldApiKey) {
|
|
1332
|
+
const canUseSavedSession =
|
|
1333
|
+
Boolean(out.sessionCookie) &&
|
|
1334
|
+
(!savedSession ||
|
|
1335
|
+
(normalizeHttpUrl(out.baseUrl) === normalizeHttpUrl(savedSession?.baseUrl) &&
|
|
1336
|
+
(!out.tenantId || String(out.tenantId ?? "").trim() === String(savedSession?.tenantId ?? "").trim())));
|
|
1337
|
+
const keyOptions = [];
|
|
1338
|
+
if (canUseSavedSession) {
|
|
1339
|
+
keyOptions.push({
|
|
1340
|
+
value: "session",
|
|
1341
|
+
label: "Use saved login session",
|
|
1342
|
+
hint: `Reuse ${out.sessionFile} to mint runtime key`
|
|
1343
|
+
});
|
|
1344
|
+
} else {
|
|
1345
|
+
keyOptions.push({
|
|
1346
|
+
value: "login",
|
|
1347
|
+
label: "Login / create tenant (recommended)",
|
|
1348
|
+
hint: "OTP sign-in; no API key required"
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
keyOptions.push(
|
|
1352
|
+
{ value: "bootstrap", label: "Generate during setup", hint: "Use onboarding bootstrap API key" },
|
|
1353
|
+
{ value: "manual", label: "Paste existing key", hint: "Use an existing tenant API key" }
|
|
1354
|
+
);
|
|
1355
|
+
const keyMode = await promptSelect(
|
|
1356
|
+
rl,
|
|
1357
|
+
stdin,
|
|
1358
|
+
stdout,
|
|
1359
|
+
"How should setup get your Settld API key?",
|
|
1360
|
+
keyOptions,
|
|
1361
|
+
{ defaultValue: canUseSavedSession ? "session" : "login", color }
|
|
1362
|
+
);
|
|
1363
|
+
if (keyMode === "login") {
|
|
1364
|
+
await runLoginImpl({
|
|
1365
|
+
argv: ["--base-url", out.baseUrl, "--session-file", out.sessionFile],
|
|
1366
|
+
stdin,
|
|
1367
|
+
stdout,
|
|
1368
|
+
fetchImpl
|
|
1369
|
+
});
|
|
1370
|
+
const refreshedSession = await readSavedSessionImpl({ sessionPath: out.sessionFile });
|
|
1371
|
+
if (!refreshedSession) throw new Error("login did not produce a saved session");
|
|
1372
|
+
out.baseUrl = String(refreshedSession.baseUrl ?? out.baseUrl).trim() || out.baseUrl;
|
|
1373
|
+
out.tenantId = String(refreshedSession.tenantId ?? out.tenantId).trim();
|
|
1374
|
+
out.sessionCookie = String(refreshedSession.cookie ?? out.sessionCookie).trim();
|
|
1375
|
+
if (savedSession) {
|
|
1376
|
+
savedSession.baseUrl = refreshedSession.baseUrl;
|
|
1377
|
+
savedSession.tenantId = refreshedSession.tenantId;
|
|
1378
|
+
savedSession.cookie = refreshedSession.cookie;
|
|
1379
|
+
}
|
|
1380
|
+
continue;
|
|
1171
1381
|
}
|
|
1172
|
-
if (
|
|
1173
|
-
out.
|
|
1382
|
+
if (keyMode === "bootstrap") {
|
|
1383
|
+
if (!out.bootstrapApiKey) {
|
|
1384
|
+
out.bootstrapApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Onboarding bootstrap API key");
|
|
1385
|
+
}
|
|
1386
|
+
if (!out.bootstrapKeyId) {
|
|
1387
|
+
out.bootstrapKeyId = await promptLine(rl, "Generated key ID (optional)", { required: false });
|
|
1388
|
+
}
|
|
1389
|
+
if (!out.bootstrapScopes) {
|
|
1390
|
+
out.bootstrapScopes = await promptLine(rl, "Generated key scopes CSV (optional)", { required: false });
|
|
1391
|
+
}
|
|
1392
|
+
break;
|
|
1174
1393
|
}
|
|
1175
|
-
if (
|
|
1176
|
-
out.
|
|
1394
|
+
if (keyMode === "manual") {
|
|
1395
|
+
out.settldApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Settld API key");
|
|
1396
|
+
break;
|
|
1177
1397
|
}
|
|
1178
|
-
} else if (keyMode === "manual") {
|
|
1179
|
-
out.settldApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Settld API key");
|
|
1180
|
-
} else {
|
|
1181
1398
|
out.bootstrapApiKey = "";
|
|
1399
|
+
break;
|
|
1182
1400
|
}
|
|
1183
1401
|
}
|
|
1402
|
+
if (!out.tenantId) {
|
|
1403
|
+
out.tenantId = await promptLine(rl, "Tenant ID", { defaultValue: "tenant_default" });
|
|
1404
|
+
}
|
|
1184
1405
|
|
|
1185
1406
|
if (out.walletMode === "managed") {
|
|
1186
|
-
out.
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1407
|
+
if (out.setupMode === "quick") {
|
|
1408
|
+
out.walletBootstrap = out.walletBootstrap || "auto";
|
|
1409
|
+
} else {
|
|
1410
|
+
out.walletBootstrap = await promptSelect(
|
|
1411
|
+
rl,
|
|
1412
|
+
stdin,
|
|
1413
|
+
stdout,
|
|
1414
|
+
"Managed wallet bootstrap",
|
|
1415
|
+
[
|
|
1416
|
+
{ value: "auto", label: "auto", hint: "Use local Circle key when present, else remote bootstrap" },
|
|
1417
|
+
{ value: "local", label: "local", hint: "Always use local Circle API key flow" },
|
|
1418
|
+
{ value: "remote", label: "remote", hint: "Always use tenant onboarding endpoint" }
|
|
1419
|
+
],
|
|
1420
|
+
{ defaultValue: out.walletBootstrap || "auto", color }
|
|
1421
|
+
);
|
|
1422
|
+
}
|
|
1198
1423
|
if (out.walletBootstrap === "local" && !out.circleApiKey) {
|
|
1199
1424
|
out.circleApiKey = await promptSecretLine(rl, mutableOutput, stdout, "Circle API key");
|
|
1200
1425
|
}
|
|
@@ -1220,6 +1445,9 @@ async function resolveRuntimeConfig({
|
|
|
1220
1445
|
out.smoke = false;
|
|
1221
1446
|
out.skipProfileApply = true;
|
|
1222
1447
|
out.dryRun = true;
|
|
1448
|
+
out.guidedNext = false;
|
|
1449
|
+
} else if (out.setupMode === "quick") {
|
|
1450
|
+
out.profileId = out.profileId || "engineering-spend";
|
|
1223
1451
|
} else {
|
|
1224
1452
|
out.preflight = await promptBooleanChoice(
|
|
1225
1453
|
rl,
|
|
@@ -1296,7 +1524,10 @@ export async function runOnboard({
|
|
|
1296
1524
|
requestRuntimeBootstrapMcpEnvImpl = requestRuntimeBootstrapMcpEnv,
|
|
1297
1525
|
requestRemoteWalletBootstrapImpl = requestRemoteWalletBootstrap,
|
|
1298
1526
|
runPreflightChecksImpl = runPreflightChecks,
|
|
1299
|
-
detectInstalledHostsImpl = detectInstalledHosts
|
|
1527
|
+
detectInstalledHostsImpl = detectInstalledHosts,
|
|
1528
|
+
runLoginImpl = runLogin,
|
|
1529
|
+
readSavedSessionImpl = readSavedSession,
|
|
1530
|
+
runWalletCliImpl = runWalletCli
|
|
1300
1531
|
} = {}) {
|
|
1301
1532
|
const args = parseArgs(argv);
|
|
1302
1533
|
if (args.help) {
|
|
@@ -1305,7 +1536,7 @@ export async function runOnboard({
|
|
|
1305
1536
|
}
|
|
1306
1537
|
|
|
1307
1538
|
const showSteps = args.format !== "json";
|
|
1308
|
-
const totalSteps = args.preflightOnly ? 4 :
|
|
1539
|
+
const totalSteps = args.preflightOnly ? 4 : 6;
|
|
1309
1540
|
let step = 1;
|
|
1310
1541
|
|
|
1311
1542
|
if (showSteps) printStep(stdout, step, totalSteps, "Resolve setup configuration");
|
|
@@ -1314,7 +1545,10 @@ export async function runOnboard({
|
|
|
1314
1545
|
runtimeEnv,
|
|
1315
1546
|
stdin,
|
|
1316
1547
|
stdout,
|
|
1317
|
-
detectInstalledHostsImpl
|
|
1548
|
+
detectInstalledHostsImpl,
|
|
1549
|
+
fetchImpl,
|
|
1550
|
+
runLoginImpl,
|
|
1551
|
+
readSavedSessionImpl
|
|
1318
1552
|
});
|
|
1319
1553
|
step += 1;
|
|
1320
1554
|
const normalizedBaseUrl = normalizeHttpUrl(mustString(config.baseUrl, "SETTLD_BASE_URL / --base-url"));
|
|
@@ -1453,6 +1687,12 @@ export async function runOnboard({
|
|
|
1453
1687
|
lines.push(`Settld: ${normalizedBaseUrl} (tenant=${tenantId})`);
|
|
1454
1688
|
lines.push(`Wallet mode: ${config.walletMode}`);
|
|
1455
1689
|
lines.push(`Wallet bootstrap mode: ${walletBootstrapMode}`);
|
|
1690
|
+
if (config.walletMode !== "none") {
|
|
1691
|
+
lines.push("Wallet next steps:");
|
|
1692
|
+
lines.push("- settld wallet status");
|
|
1693
|
+
lines.push("- settld wallet fund --method transfer");
|
|
1694
|
+
lines.push("- settld wallet balance --watch --min-usdc 1");
|
|
1695
|
+
}
|
|
1456
1696
|
if (args.outEnv) lines.push(`Wrote env file: ${args.outEnv}`);
|
|
1457
1697
|
if (args.reportPath) lines.push(`Wrote report: ${args.reportPath}`);
|
|
1458
1698
|
lines.push("");
|
|
@@ -1506,9 +1746,27 @@ export async function runOnboard({
|
|
|
1506
1746
|
await fs.writeFile(args.outEnv, toEnvFileText(mergedEnv), "utf8");
|
|
1507
1747
|
}
|
|
1508
1748
|
|
|
1749
|
+
if (showSteps) printStep(stdout, step, totalSteps, "Guided next steps");
|
|
1750
|
+
const guided = await runGuidedQuickFlow({
|
|
1751
|
+
enabled: Boolean(config.setupMode === "quick" && config.guidedNext),
|
|
1752
|
+
walletMode: config.walletMode,
|
|
1753
|
+
normalizedBaseUrl,
|
|
1754
|
+
tenantId,
|
|
1755
|
+
sessionFile: config.sessionFile,
|
|
1756
|
+
sessionCookie: config.sessionCookie,
|
|
1757
|
+
mergedEnv,
|
|
1758
|
+
runtimeEnv,
|
|
1759
|
+
stdin,
|
|
1760
|
+
stdout,
|
|
1761
|
+
runWalletCliImpl
|
|
1762
|
+
});
|
|
1763
|
+
step += 1;
|
|
1764
|
+
|
|
1509
1765
|
if (showSteps) printStep(stdout, step, totalSteps, "Finalize output");
|
|
1510
1766
|
const payload = {
|
|
1511
1767
|
ok: true,
|
|
1768
|
+
setupMode: config.setupMode,
|
|
1769
|
+
guided,
|
|
1512
1770
|
host: config.host,
|
|
1513
1771
|
wallet: {
|
|
1514
1772
|
mode: config.walletMode,
|
|
@@ -1540,6 +1798,7 @@ export async function runOnboard({
|
|
|
1540
1798
|
lines.push("Settld onboard complete.");
|
|
1541
1799
|
lines.push(`Host: ${config.host}`);
|
|
1542
1800
|
lines.push(`Settld: ${normalizedBaseUrl} (tenant=${tenantId})`);
|
|
1801
|
+
lines.push(`Setup mode: ${config.setupMode}`);
|
|
1543
1802
|
lines.push(`Preflight: ${config.preflight ? "passed" : "skipped"}`);
|
|
1544
1803
|
lines.push(`Wallet mode: ${config.walletMode}`);
|
|
1545
1804
|
lines.push(`Wallet bootstrap mode: ${walletBootstrapMode}`);
|
|
@@ -1547,6 +1806,18 @@ export async function runOnboard({
|
|
|
1547
1806
|
if (wallet?.wallets?.escrow?.walletId) lines.push(`Escrow wallet: ${wallet.wallets.escrow.walletId}`);
|
|
1548
1807
|
if (wallet?.tokenIdUsdc) lines.push(`USDC token id: ${wallet.tokenIdUsdc}`);
|
|
1549
1808
|
if (args.outEnv) lines.push(`Wrote env file: ${args.outEnv}`);
|
|
1809
|
+
if (guided?.enabled) {
|
|
1810
|
+
lines.push("");
|
|
1811
|
+
lines.push("Guided quick flow:");
|
|
1812
|
+
if (guided.ran) {
|
|
1813
|
+
lines.push(`- wallet fund: ${guided.walletFund?.ok ? "ok" : "not completed"}`);
|
|
1814
|
+
lines.push(`- wallet balance watch: ${guided.walletBalanceWatch?.ok ? "ok" : "not completed"}`);
|
|
1815
|
+
lines.push(`- first paid call: ${guided.firstPaidCall?.ok ? "ok" : "failed"}`);
|
|
1816
|
+
} else {
|
|
1817
|
+
lines.push("- skipped");
|
|
1818
|
+
}
|
|
1819
|
+
for (const warning of guided.warnings ?? []) lines.push(`- warning: ${warning}`);
|
|
1820
|
+
}
|
|
1550
1821
|
lines.push("");
|
|
1551
1822
|
lines.push("Combined exports:");
|
|
1552
1823
|
lines.push(toExportText(mergedEnv));
|
|
@@ -1557,6 +1828,14 @@ export async function runOnboard({
|
|
|
1557
1828
|
lines.push(`${step}. ${row}`);
|
|
1558
1829
|
step += 1;
|
|
1559
1830
|
}
|
|
1831
|
+
if (config.walletMode !== "none") {
|
|
1832
|
+
lines.push(`${step}. Run \`settld wallet status\` to confirm wallet wiring.`);
|
|
1833
|
+
step += 1;
|
|
1834
|
+
lines.push(`${step}. Fund with \`settld wallet fund --method transfer\` (or \`--method card --open\` if hosted links are configured).`);
|
|
1835
|
+
step += 1;
|
|
1836
|
+
lines.push(`${step}. Confirm funds: \`settld wallet balance --watch --min-usdc 1\`.`);
|
|
1837
|
+
step += 1;
|
|
1838
|
+
}
|
|
1560
1839
|
lines.push(`${step}. Run \`npm run mcp:probe\` for an immediate health check.`);
|
|
1561
1840
|
stdout.write(`${lines.join("\n")}\n`);
|
|
1562
1841
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
-
if
|
|
5
|
-
echo "MkDocs
|
|
4
|
+
if ! python3 -m mkdocs --version >/dev/null 2>&1; then
|
|
5
|
+
echo "MkDocs not found; running install step first..."
|
|
6
6
|
bash scripts/vercel/install-mkdocs.sh
|
|
7
7
|
fi
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
python3 -m mkdocs build --strict --config-file mkdocs.yml
|
|
@@ -5,6 +5,9 @@ set -euo pipefail
|
|
|
5
5
|
# - exit 0 => skip deployment
|
|
6
6
|
# - exit 1 => continue with deployment
|
|
7
7
|
|
|
8
|
+
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
|
9
|
+
cd "$REPO_ROOT"
|
|
10
|
+
|
|
8
11
|
if ! git rev-parse --verify HEAD^ >/dev/null 2>&1; then
|
|
9
12
|
# No parent commit context available; build to stay safe.
|
|
10
13
|
exit 1
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
|
-
python3 -m
|
|
5
|
-
|
|
6
|
-
.vercel-venv/bin/pip install mkdocs mkdocs-material
|
|
4
|
+
python3 -m pip install --break-system-packages --upgrade pip setuptools wheel
|
|
5
|
+
python3 -m pip install --break-system-packages mkdocs mkdocs-material
|