@candledottv/cli 0.8.3 → 0.8.4
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/dist/index.js +151 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -18850,6 +18850,42 @@ var init_convert = __esm(() => {
|
|
|
18850
18850
|
DECIMAL_RE = /^\d+(\.\d+)?$/;
|
|
18851
18851
|
});
|
|
18852
18852
|
|
|
18853
|
+
// ../mcp/src/version.ts
|
|
18854
|
+
var SERVER_VERSION = "0.6.4";
|
|
18855
|
+
|
|
18856
|
+
// ../mcp/src/update-notice.ts
|
|
18857
|
+
function newer(a, b) {
|
|
18858
|
+
const [a1 = 0, a2 = 0, a3 = 0] = a.split(".").map(Number);
|
|
18859
|
+
const [b1 = 0, b2 = 0, b3 = 0] = b.split(".").map(Number);
|
|
18860
|
+
return a1 !== b1 ? a1 > b1 : a2 !== b2 ? a2 > b2 : a3 > b3;
|
|
18861
|
+
}
|
|
18862
|
+
function noteVersionHeaders(res) {
|
|
18863
|
+
const headers = res?.headers;
|
|
18864
|
+
const value = typeof headers?.get === "function" ? headers.get("x-candle-mcp-latest") : null;
|
|
18865
|
+
if (!value || !PLAIN_VERSION.test(value))
|
|
18866
|
+
return;
|
|
18867
|
+
if (latestSeen !== null && !newer(value, latestSeen))
|
|
18868
|
+
return;
|
|
18869
|
+
latestSeen = value;
|
|
18870
|
+
if (!warned && newer(value, SERVER_VERSION) && !process.env.CANDLE_NO_UPDATE_NOTIFIER) {
|
|
18871
|
+
warned = true;
|
|
18872
|
+
console.error(`@candledottv/mcp ${value} is available (running ${SERVER_VERSION}). Update: npm install -g @candledottv/mcp@latest`);
|
|
18873
|
+
}
|
|
18874
|
+
}
|
|
18875
|
+
function updateAvailable() {
|
|
18876
|
+
if (latestSeen === null || !newer(latestSeen, SERVER_VERSION))
|
|
18877
|
+
return null;
|
|
18878
|
+
return {
|
|
18879
|
+
current: SERVER_VERSION,
|
|
18880
|
+
latest: latestSeen,
|
|
18881
|
+
command: "npm install -g @candledottv/mcp@latest"
|
|
18882
|
+
};
|
|
18883
|
+
}
|
|
18884
|
+
var PLAIN_VERSION, latestSeen = null, warned = false;
|
|
18885
|
+
var init_update_notice = __esm(() => {
|
|
18886
|
+
PLAIN_VERSION = /^\d+\.\d+\.\d+$/;
|
|
18887
|
+
});
|
|
18888
|
+
|
|
18853
18889
|
// ../mcp/src/orchestrate.ts
|
|
18854
18890
|
import { randomUUID } from "node:crypto";
|
|
18855
18891
|
function requireApiKey(cfg) {
|
|
@@ -19156,6 +19192,7 @@ async function executionStatus(cfg, doFetch) {
|
|
|
19156
19192
|
const apiKey = requireApiKey(cfg);
|
|
19157
19193
|
const get = async (path) => {
|
|
19158
19194
|
const res = await doFetch(`${base(cfg)}${path}`, { method: "GET", headers: headers(apiKey) });
|
|
19195
|
+
noteVersionHeaders(res);
|
|
19159
19196
|
const text = await res.text();
|
|
19160
19197
|
let body;
|
|
19161
19198
|
try {
|
|
@@ -19181,6 +19218,7 @@ async function executionStatus(cfg, doFetch) {
|
|
|
19181
19218
|
success: true,
|
|
19182
19219
|
ready: unreadable.length === 0 ? true : undefined,
|
|
19183
19220
|
notice: tierBody?.maxExpired ? tierBody.maxExpiredNotice : undefined,
|
|
19221
|
+
updateAvailable: updateAvailable() ?? undefined,
|
|
19184
19222
|
unreadable: unreadable.length > 0 ? unreadable.map(([name]) => name) : undefined,
|
|
19185
19223
|
wallets: wallets2.body,
|
|
19186
19224
|
tier: tier.body,
|
|
@@ -19192,6 +19230,7 @@ async function executionStatus(cfg, doFetch) {
|
|
|
19192
19230
|
var SWEEP_BASE_ASSETS;
|
|
19193
19231
|
var init_orchestrate = __esm(() => {
|
|
19194
19232
|
init_convert();
|
|
19233
|
+
init_update_notice();
|
|
19195
19234
|
SWEEP_BASE_ASSETS = {
|
|
19196
19235
|
solana: ["USDC", "CNDL", "SOL"],
|
|
19197
19236
|
hood: ["USDG", "ETH"]
|
|
@@ -19321,6 +19360,7 @@ function buildRequest(name, args, cfg) {
|
|
|
19321
19360
|
async function callAndRelay(name, args, cfg) {
|
|
19322
19361
|
const { url, init } = buildRequest(name, args, cfg);
|
|
19323
19362
|
const res = await fetch(url, init);
|
|
19363
|
+
noteVersionHeaders(res);
|
|
19324
19364
|
const text = await res.text();
|
|
19325
19365
|
return {
|
|
19326
19366
|
content: [{ type: "text", text }],
|
|
@@ -19448,6 +19488,7 @@ var init_tools = __esm(() => {
|
|
|
19448
19488
|
init_zod();
|
|
19449
19489
|
init_convert();
|
|
19450
19490
|
init_orchestrate();
|
|
19491
|
+
init_update_notice();
|
|
19451
19492
|
TOOL_NAMES = [
|
|
19452
19493
|
"candle_launch_token",
|
|
19453
19494
|
"candle_get_market",
|
|
@@ -19546,9 +19587,6 @@ var init_tools = __esm(() => {
|
|
|
19546
19587
|
};
|
|
19547
19588
|
});
|
|
19548
19589
|
|
|
19549
|
-
// ../mcp/src/version.ts
|
|
19550
|
-
var SERVER_VERSION = "0.6.3";
|
|
19551
|
-
|
|
19552
19590
|
// ../mcp/src/server.ts
|
|
19553
19591
|
var exports_server = {};
|
|
19554
19592
|
__export(exports_server, {
|
|
@@ -19677,6 +19715,10 @@ function classifyError(status, raw) {
|
|
|
19677
19715
|
}
|
|
19678
19716
|
return { message: `Request failed with status ${status}` };
|
|
19679
19717
|
}
|
|
19718
|
+
var latestCliVersionSeen = null;
|
|
19719
|
+
function latestCliVersionFromApi() {
|
|
19720
|
+
return latestCliVersionSeen;
|
|
19721
|
+
}
|
|
19680
19722
|
async function apiRequest(path, opts) {
|
|
19681
19723
|
const url = buildUrl(opts.apiUrl, path);
|
|
19682
19724
|
const insecure = insecureApiUrlFault(opts.apiUrl, opts.env ?? process.env);
|
|
@@ -19704,6 +19746,9 @@ async function apiRequest(path, opts) {
|
|
|
19704
19746
|
raw: undefined
|
|
19705
19747
|
};
|
|
19706
19748
|
}
|
|
19749
|
+
const latestHeader = response.headers?.get?.("x-candle-cli-latest");
|
|
19750
|
+
if (latestHeader)
|
|
19751
|
+
latestCliVersionSeen = latestHeader;
|
|
19707
19752
|
const text = await response.text();
|
|
19708
19753
|
const raw = parseBody(text);
|
|
19709
19754
|
if (response.ok) {
|
|
@@ -20260,7 +20305,7 @@ async function resolveApiKey(deps, profile) {
|
|
|
20260
20305
|
}
|
|
20261
20306
|
|
|
20262
20307
|
// src/version.ts
|
|
20263
|
-
var CLI_VERSION = "0.8.
|
|
20308
|
+
var CLI_VERSION = "0.8.4";
|
|
20264
20309
|
|
|
20265
20310
|
// src/commands/auth.ts
|
|
20266
20311
|
var DEVICE_CODE_PATH = "/api/v1/agent/device/code";
|
|
@@ -20602,6 +20647,9 @@ async function authStatus(args, ctx) {
|
|
|
20602
20647
|
var RELEASE_BASE_URL = "https://github.com/candledottv/agentic";
|
|
20603
20648
|
var RELEASE_ISSUER = "https://token.actions.githubusercontent.com";
|
|
20604
20649
|
var VERSION = /^\d+\.\d+\.\d+$/;
|
|
20650
|
+
function isPlainVersion(value) {
|
|
20651
|
+
return VERSION.test(value);
|
|
20652
|
+
}
|
|
20605
20653
|
function releaseIdentityUri(version) {
|
|
20606
20654
|
if (!VERSION.test(version))
|
|
20607
20655
|
throw new Error(`invalid release version: ${version}`);
|
|
@@ -21538,6 +21586,58 @@ Console (keys, funding, withdrawal addresses, limits): ${portalDeviceUrl(apiUrl,
|
|
|
21538
21586
|
// src/commands/update.ts
|
|
21539
21587
|
import { createHash as createHash2, randomBytes } from "node:crypto";
|
|
21540
21588
|
|
|
21589
|
+
// src/progress.ts
|
|
21590
|
+
var FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
21591
|
+
var INTERVAL_MS = 80;
|
|
21592
|
+
function stepReporter(write, tty) {
|
|
21593
|
+
let timer = null;
|
|
21594
|
+
let frame = 0;
|
|
21595
|
+
let current = null;
|
|
21596
|
+
const clearSpinner = () => {
|
|
21597
|
+
if (timer !== null)
|
|
21598
|
+
clearInterval(timer);
|
|
21599
|
+
timer = null;
|
|
21600
|
+
if (tty && current !== null)
|
|
21601
|
+
write("\r\x1B[2K");
|
|
21602
|
+
current = null;
|
|
21603
|
+
};
|
|
21604
|
+
return {
|
|
21605
|
+
start(label) {
|
|
21606
|
+
clearSpinner();
|
|
21607
|
+
current = label;
|
|
21608
|
+
if (!tty) {
|
|
21609
|
+
write(`${label}...
|
|
21610
|
+
`);
|
|
21611
|
+
return;
|
|
21612
|
+
}
|
|
21613
|
+
write(`${FRAMES[0]} ${label}`);
|
|
21614
|
+
frame = 1;
|
|
21615
|
+
timer = setInterval(() => {
|
|
21616
|
+
write(`\r\x1B[2K${FRAMES[frame % FRAMES.length]} ${current}`);
|
|
21617
|
+
frame++;
|
|
21618
|
+
}, INTERVAL_MS);
|
|
21619
|
+
if (typeof timer === "object" && "unref" in timer)
|
|
21620
|
+
timer.unref();
|
|
21621
|
+
},
|
|
21622
|
+
done(label) {
|
|
21623
|
+
clearSpinner();
|
|
21624
|
+
write(`✓ ${label}
|
|
21625
|
+
`);
|
|
21626
|
+
},
|
|
21627
|
+
fail(label) {
|
|
21628
|
+
clearSpinner();
|
|
21629
|
+
write(`✗ ${label}
|
|
21630
|
+
`);
|
|
21631
|
+
},
|
|
21632
|
+
stop: clearSpinner
|
|
21633
|
+
};
|
|
21634
|
+
}
|
|
21635
|
+
function formatBytes(n) {
|
|
21636
|
+
if (n >= 1024 * 1024)
|
|
21637
|
+
return `${(n / (1024 * 1024)).toFixed(1)} MB`;
|
|
21638
|
+
return `${Math.max(1, Math.round(n / 1024))} KB`;
|
|
21639
|
+
}
|
|
21640
|
+
|
|
21541
21641
|
// src/bun-crypto-shim.ts
|
|
21542
21642
|
import crypto2, { KeyObject } from "node:crypto";
|
|
21543
21643
|
var original = crypto2.verify.bind(crypto2);
|
|
@@ -21880,12 +21980,19 @@ async function update(args, ctx) {
|
|
|
21880
21980
|
}, json);
|
|
21881
21981
|
return 1;
|
|
21882
21982
|
}
|
|
21983
|
+
const steps = json ? stepReporter(() => {}, false) : stepReporter((text) => deps.stderr.write(text), process.stderr.isTTY === true);
|
|
21984
|
+
if (!json)
|
|
21985
|
+
deps.stderr.write(`Updating candle ${CLI_VERSION} -> ${target.version}
|
|
21986
|
+
`);
|
|
21987
|
+
steps.start(`downloading ${expectedName}`);
|
|
21883
21988
|
const download = await fetchAll(deps, base, target.tag, expectedName);
|
|
21884
21989
|
if (!download.ok) {
|
|
21990
|
+
steps.fail(`downloading ${expectedName}`);
|
|
21885
21991
|
writeLocalFailure(deps, { code: "UPDATE_UNREACHABLE", message: download.message }, json);
|
|
21886
21992
|
return 1;
|
|
21887
21993
|
}
|
|
21888
21994
|
const { bytes, sums, bundle } = download;
|
|
21995
|
+
steps.done(`downloaded ${expectedName} (${formatBytes(bytes.length)})`);
|
|
21889
21996
|
const dir = realExec.slice(0, realExec.lastIndexOf("/")) || ".";
|
|
21890
21997
|
const tmpPath = `${dir}/.candle-update-${target.version}-${randomBytes(6).toString("hex")}`;
|
|
21891
21998
|
try {
|
|
@@ -21894,10 +22001,12 @@ async function update(args, ctx) {
|
|
|
21894
22001
|
writeLocalFailure(deps, notWritable(dir, error), json);
|
|
21895
22002
|
return 1;
|
|
21896
22003
|
}
|
|
22004
|
+
steps.start("verifying checksum");
|
|
21897
22005
|
const actual = createHash2("sha256").update(bytes).digest("hex");
|
|
21898
22006
|
const fromSums = sums.split(`
|
|
21899
22007
|
`).map((line) => line.trim().split(/\s+/)).find((parts) => parts[1] === expectedName)?.[0];
|
|
21900
22008
|
if (actual !== asset.sha256 || actual !== fromSums) {
|
|
22009
|
+
steps.fail("verifying checksum");
|
|
21901
22010
|
await discard(deps, tmpPath);
|
|
21902
22011
|
writeLocalFailure(deps, {
|
|
21903
22012
|
code: "UPDATE_VERIFY_FAILED",
|
|
@@ -21905,9 +22014,12 @@ async function update(args, ctx) {
|
|
|
21905
22014
|
}, json);
|
|
21906
22015
|
return 1;
|
|
21907
22016
|
}
|
|
22017
|
+
steps.done("checksum verified");
|
|
22018
|
+
steps.start("verifying signature");
|
|
21908
22019
|
const verify = deps.verify ?? verifyReleaseAsset;
|
|
21909
22020
|
const verdict = verify(bytes, bundle, identityUri, RELEASE_ISSUER);
|
|
21910
22021
|
if (!verdict.ok) {
|
|
22022
|
+
steps.fail("verifying signature");
|
|
21911
22023
|
await discard(deps, tmpPath);
|
|
21912
22024
|
writeLocalFailure(deps, {
|
|
21913
22025
|
code: "UPDATE_VERIFY_FAILED",
|
|
@@ -21916,13 +22028,17 @@ async function update(args, ctx) {
|
|
|
21916
22028
|
}, json);
|
|
21917
22029
|
return 1;
|
|
21918
22030
|
}
|
|
22031
|
+
steps.done("signature verified");
|
|
22032
|
+
steps.start("installing");
|
|
21919
22033
|
try {
|
|
21920
22034
|
await deps.rename(tmpPath, realExec);
|
|
21921
22035
|
} catch (error) {
|
|
22036
|
+
steps.fail("installing");
|
|
21922
22037
|
await discard(deps, tmpPath);
|
|
21923
22038
|
writeLocalFailure(deps, notWritable(dir, error), json);
|
|
21924
22039
|
return 1;
|
|
21925
22040
|
}
|
|
22041
|
+
steps.done(`installed to ${realExec}`);
|
|
21926
22042
|
if (json) {
|
|
21927
22043
|
const payload = { current: CLI_VERSION, latest: target.version, updated: true, path: realExec };
|
|
21928
22044
|
deps.stdout.write(`${JSON.stringify(payload)}
|
|
@@ -28500,6 +28616,30 @@ async function resolveSecretStore(platform = process.platform) {
|
|
|
28500
28616
|
return { store: new EncryptedFileSecretStore, backend: "encrypted-file" };
|
|
28501
28617
|
}
|
|
28502
28618
|
|
|
28619
|
+
// src/update-notice.ts
|
|
28620
|
+
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
28621
|
+
async function maybeWriteUpdateNotice(deps, opts = {}) {
|
|
28622
|
+
try {
|
|
28623
|
+
if (deps.env.CANDLE_NO_UPDATE_NOTIFIER)
|
|
28624
|
+
return;
|
|
28625
|
+
if (opts.command === "update" || opts.command === "doctor")
|
|
28626
|
+
return;
|
|
28627
|
+
const latest = latestCliVersionFromApi();
|
|
28628
|
+
if (!latest || !isPlainVersion(latest) || compareVersions(latest, CLI_VERSION) <= 0)
|
|
28629
|
+
return;
|
|
28630
|
+
const config = await deps.readConfig();
|
|
28631
|
+
const prior = config.updateNotice;
|
|
28632
|
+
if (prior && prior.version === latest && deps.now() - prior.shownAt < DAY_MS)
|
|
28633
|
+
return;
|
|
28634
|
+
const line = `Update available: candle ${CLI_VERSION} -> ${latest}. Run: candle update`;
|
|
28635
|
+
const tty = process.stderr.isTTY === true;
|
|
28636
|
+
deps.stderr.write(tty ? `\x1B[2m${line}\x1B[0m
|
|
28637
|
+
` : `${line}
|
|
28638
|
+
`);
|
|
28639
|
+
await deps.writeConfig({ updateNotice: { version: latest, shownAt: deps.now() } });
|
|
28640
|
+
} catch {}
|
|
28641
|
+
}
|
|
28642
|
+
|
|
28503
28643
|
// src/index.ts
|
|
28504
28644
|
function extractGlobalFlags(argv) {
|
|
28505
28645
|
const rest = [];
|
|
@@ -28616,6 +28756,13 @@ function routesToCommand(cmd, sub) {
|
|
|
28616
28756
|
}
|
|
28617
28757
|
var NEVER_GUARDED = new Set(["auth", "profile", "doctor", "verify", "update"]);
|
|
28618
28758
|
async function run2(argv, deps) {
|
|
28759
|
+
const code = await runCommand(argv, deps);
|
|
28760
|
+
const extractedForNotice = extractGlobalFlags(argv);
|
|
28761
|
+
const word = "error" in extractedForNotice ? undefined : canonicalCommand(extractedForNotice.rest[0] === "candle" ? extractedForNotice.rest[1] : extractedForNotice.rest[0]);
|
|
28762
|
+
await maybeWriteUpdateNotice(deps, { command: word });
|
|
28763
|
+
return code;
|
|
28764
|
+
}
|
|
28765
|
+
async function runCommand(argv, deps) {
|
|
28619
28766
|
const extracted = extractGlobalFlags(argv);
|
|
28620
28767
|
if ("error" in extracted) {
|
|
28621
28768
|
deps.stderr.write(`${extracted.error}
|
package/package.json
CHANGED