claudemesh-cli 0.9.4 → 0.9.5
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 +247 -144
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -40069,7 +40069,7 @@ function moveTo(row, col) {
|
|
|
40069
40069
|
function visibleLength(s) {
|
|
40070
40070
|
return s.replace(/\x1b\[[^m]*m/g, "").length;
|
|
40071
40071
|
}
|
|
40072
|
-
var isTTY, esc2 = (code) => (s) => isTTY ? `${code}${s}\x1B[0m` : s, orange, clay, amber, bold2, dim,
|
|
40072
|
+
var isTTY, esc2 = (code) => (s) => isTTY ? `${code}${s}\x1B[0m` : s, orange, clay, amber, bold2, dim, green2, yellow, red, cyan2, boldOrange, HIDE_CURSOR, SHOW_CURSOR, CLEAR_SCREEN, CLEAR_LINE;
|
|
40073
40073
|
var init_colors = __esm(() => {
|
|
40074
40074
|
isTTY = process.stdout.isTTY && !process.env.NO_COLOR && process.env.TERM !== "dumb";
|
|
40075
40075
|
orange = esc2("\x1B[38;5;208m");
|
|
@@ -40077,7 +40077,7 @@ var init_colors = __esm(() => {
|
|
|
40077
40077
|
amber = esc2("\x1B[38;5;214m");
|
|
40078
40078
|
bold2 = esc2("\x1B[1m");
|
|
40079
40079
|
dim = esc2("\x1B[2m");
|
|
40080
|
-
|
|
40080
|
+
green2 = esc2("\x1B[32m");
|
|
40081
40081
|
yellow = esc2("\x1B[33m");
|
|
40082
40082
|
red = esc2("\x1B[31m");
|
|
40083
40083
|
cyan2 = esc2("\x1B[36m");
|
|
@@ -40093,7 +40093,7 @@ var package_default;
|
|
|
40093
40093
|
var init_package = __esm(() => {
|
|
40094
40094
|
package_default = {
|
|
40095
40095
|
name: "claudemesh-cli",
|
|
40096
|
-
version: "0.9.
|
|
40096
|
+
version: "0.9.5",
|
|
40097
40097
|
description: "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
40098
40098
|
keywords: [
|
|
40099
40099
|
"claude-code",
|
|
@@ -53943,14 +53943,24 @@ function center(s) {
|
|
|
53943
53943
|
function writeCentered(row, s) {
|
|
53944
53944
|
process.stdout.write(moveTo(row, 1) + center(s) + CLEAR_LINE);
|
|
53945
53945
|
}
|
|
53946
|
-
function drawTopBar() {
|
|
53946
|
+
function drawTopBar(extra) {
|
|
53947
53947
|
const { cols } = termSize();
|
|
53948
|
-
const
|
|
53949
|
-
const
|
|
53950
|
-
const
|
|
53951
|
-
const
|
|
53952
|
-
const
|
|
53953
|
-
|
|
53948
|
+
const bg = "\x1B[48;5;208m\x1B[30m";
|
|
53949
|
+
const reset = "\x1B[0m";
|
|
53950
|
+
const left = ` claudemesh v${VERSION}`;
|
|
53951
|
+
const right = `claudemesh.com `;
|
|
53952
|
+
const mid = extra ? ` ${extra}` : "";
|
|
53953
|
+
const gap = Math.max(1, cols - left.length - right.length - mid.length);
|
|
53954
|
+
process.stdout.write(moveTo(1, 1) + bg + left + mid + " ".repeat(gap) + right + reset);
|
|
53955
|
+
}
|
|
53956
|
+
function drawBottomBar(left, right) {
|
|
53957
|
+
const { cols, rows } = termSize();
|
|
53958
|
+
const bg = "\x1B[48;5;208m\x1B[30m";
|
|
53959
|
+
const reset = "\x1B[0m";
|
|
53960
|
+
const l = ` ${left}`;
|
|
53961
|
+
const r = right ? `${right} ` : "";
|
|
53962
|
+
const gap = Math.max(1, cols - l.length - r.length);
|
|
53963
|
+
process.stdout.write(moveTo(rows, 1) + bg + l + " ".repeat(gap) + r + reset);
|
|
53954
53964
|
}
|
|
53955
53965
|
function enterFullScreen() {
|
|
53956
53966
|
process.stdout.write(HIDE_CURSOR + CLEAR_SCREEN);
|
|
@@ -54000,6 +54010,87 @@ async function menuSelect(opts) {
|
|
|
54000
54010
|
stdin.on("data", onData);
|
|
54001
54011
|
});
|
|
54002
54012
|
}
|
|
54013
|
+
async function textInput(opts) {
|
|
54014
|
+
const { label, row, placeholder } = opts;
|
|
54015
|
+
let value = "";
|
|
54016
|
+
const render = () => {
|
|
54017
|
+
const display = value || dim(placeholder ?? "");
|
|
54018
|
+
const cursor = SHOW_CURSOR;
|
|
54019
|
+
writeCentered(row, `${bold2(label)} ${display}${CLEAR_LINE}`);
|
|
54020
|
+
const fullText = `${label.replace(/\x1b\[[^m]*m/g, "")} ${value}`;
|
|
54021
|
+
const { cols } = termSize();
|
|
54022
|
+
const leftPad = Math.max(0, Math.floor((cols - fullText.length) / 2));
|
|
54023
|
+
process.stdout.write(moveTo(row, leftPad + fullText.length + 1) + cursor);
|
|
54024
|
+
};
|
|
54025
|
+
process.stdout.write(SHOW_CURSOR);
|
|
54026
|
+
render();
|
|
54027
|
+
return new Promise((resolve2) => {
|
|
54028
|
+
const stdin = process.stdin;
|
|
54029
|
+
const wasRaw = stdin.isRaw;
|
|
54030
|
+
stdin.setRawMode(true);
|
|
54031
|
+
stdin.resume();
|
|
54032
|
+
stdin.setEncoding("utf8");
|
|
54033
|
+
const onData = (key) => {
|
|
54034
|
+
if (key === "\r" || key === `
|
|
54035
|
+
`) {
|
|
54036
|
+
stdin.removeListener("data", onData);
|
|
54037
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
54038
|
+
stdin.pause();
|
|
54039
|
+
process.stdout.write(HIDE_CURSOR);
|
|
54040
|
+
const final = value || dim("skipped");
|
|
54041
|
+
writeCentered(row, `${label} ${green("✓")} ${final}${CLEAR_LINE}`);
|
|
54042
|
+
resolve2(value);
|
|
54043
|
+
} else if (key === "" || key === "\b") {
|
|
54044
|
+
value = value.slice(0, -1);
|
|
54045
|
+
render();
|
|
54046
|
+
} else if (key === "\x03") {
|
|
54047
|
+
stdin.removeListener("data", onData);
|
|
54048
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
54049
|
+
exitFullScreen();
|
|
54050
|
+
process.exit(0);
|
|
54051
|
+
} else if (key === "\x1B") {
|
|
54052
|
+
stdin.removeListener("data", onData);
|
|
54053
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
54054
|
+
stdin.pause();
|
|
54055
|
+
process.stdout.write(HIDE_CURSOR);
|
|
54056
|
+
writeCentered(row, `${label} ${dim("skipped")}${CLEAR_LINE}`);
|
|
54057
|
+
resolve2("");
|
|
54058
|
+
} else if (key >= " " && key <= "~") {
|
|
54059
|
+
value += key;
|
|
54060
|
+
render();
|
|
54061
|
+
}
|
|
54062
|
+
};
|
|
54063
|
+
stdin.on("data", onData);
|
|
54064
|
+
});
|
|
54065
|
+
}
|
|
54066
|
+
async function confirmPrompt(opts) {
|
|
54067
|
+
const { message, row } = opts;
|
|
54068
|
+
const defaultYes = opts.defaultYes ?? true;
|
|
54069
|
+
const hint = defaultYes ? `${bold2("Y")}/${dim("n")}` : `${dim("y")}/${bold2("N")}`;
|
|
54070
|
+
writeCentered(row, `${message} [${hint}]`);
|
|
54071
|
+
process.stdout.write(SHOW_CURSOR);
|
|
54072
|
+
return new Promise((resolve2) => {
|
|
54073
|
+
const stdin = process.stdin;
|
|
54074
|
+
const wasRaw = stdin.isRaw;
|
|
54075
|
+
stdin.setRawMode(true);
|
|
54076
|
+
stdin.resume();
|
|
54077
|
+
stdin.setEncoding("utf8");
|
|
54078
|
+
const onData = (key) => {
|
|
54079
|
+
stdin.removeListener("data", onData);
|
|
54080
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
54081
|
+
stdin.pause();
|
|
54082
|
+
process.stdout.write(HIDE_CURSOR);
|
|
54083
|
+
if (key === "\x03") {
|
|
54084
|
+
exitFullScreen();
|
|
54085
|
+
process.exit(0);
|
|
54086
|
+
}
|
|
54087
|
+
const yes = key === "y" || key === "Y" || key === "\r" && defaultYes;
|
|
54088
|
+
writeCentered(row, `${message} ${yes ? green("✓ yes") : dim("✗ no")}${CLEAR_LINE}`);
|
|
54089
|
+
resolve2(yes);
|
|
54090
|
+
};
|
|
54091
|
+
stdin.on("data", onData);
|
|
54092
|
+
});
|
|
54093
|
+
}
|
|
54003
54094
|
|
|
54004
54095
|
// src/commands/launch.ts
|
|
54005
54096
|
init_spinner();
|
|
@@ -54034,45 +54125,115 @@ function parseGroupsString(raw) {
|
|
|
54034
54125
|
return { name: token.slice(0, idx), role: token.slice(idx + 1) };
|
|
54035
54126
|
});
|
|
54036
54127
|
}
|
|
54037
|
-
function
|
|
54038
|
-
|
|
54039
|
-
|
|
54040
|
-
|
|
54041
|
-
|
|
54042
|
-
|
|
54043
|
-
|
|
54044
|
-
|
|
54045
|
-
}
|
|
54046
|
-
|
|
54047
|
-
|
|
54048
|
-
|
|
54049
|
-
|
|
54050
|
-
const
|
|
54051
|
-
|
|
54052
|
-
|
|
54053
|
-
|
|
54054
|
-
|
|
54055
|
-
|
|
54056
|
-
|
|
54057
|
-
|
|
54058
|
-
|
|
54059
|
-
|
|
54060
|
-
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
54061
|
-
return new Promise((resolve2, reject) => {
|
|
54062
|
-
rl.question(` ${bold3("Continue?")} [Y/n] `, (answer) => {
|
|
54063
|
-
rl.close();
|
|
54064
|
-
const a = answer.trim().toLowerCase();
|
|
54065
|
-
if (a === "" || a === "y" || a === "yes") {
|
|
54066
|
-
resolve2();
|
|
54067
|
-
} else {
|
|
54068
|
-
console.log(`
|
|
54069
|
-
Aborted. Run without autonomous mode:`);
|
|
54070
|
-
console.log(` claude --dangerously-load-development-channels server:claudemesh
|
|
54071
|
-
`);
|
|
54072
|
-
process.exit(0);
|
|
54128
|
+
async function runLaunchWizard(opts) {
|
|
54129
|
+
if (!process.stdout.isTTY) {
|
|
54130
|
+
return {
|
|
54131
|
+
role: opts.existingRole,
|
|
54132
|
+
groups: opts.existingGroups,
|
|
54133
|
+
messageMode: opts.existingMessageMode ?? "push",
|
|
54134
|
+
skipPermissions: opts.skipPermConfirm
|
|
54135
|
+
};
|
|
54136
|
+
}
|
|
54137
|
+
const { rows } = termSize();
|
|
54138
|
+
enterFullScreen();
|
|
54139
|
+
drawTopBar();
|
|
54140
|
+
drawBottomBar("↑↓ navigate ⏎ select esc skip ctrl-c quit", `mesh: ${opts.meshSlug}`);
|
|
54141
|
+
const logoTop = Math.floor((rows - FRAME_HEIGHT - 16) / 2);
|
|
54142
|
+
const brandRow = logoTop + FRAME_HEIGHT + 1;
|
|
54143
|
+
const subtitleRow = brandRow + 1;
|
|
54144
|
+
const formRow = subtitleRow + 2;
|
|
54145
|
+
writeCentered(brandRow, boldOrange("claudemesh"));
|
|
54146
|
+
writeCentered(subtitleRow, dim("peer mesh for Claude Code"));
|
|
54147
|
+
const spinner = createSpinner({
|
|
54148
|
+
render(lines) {
|
|
54149
|
+
for (let i = 0;i < lines.length; i++) {
|
|
54150
|
+
writeCentered(logoTop + i, lines[i]);
|
|
54073
54151
|
}
|
|
54074
|
-
}
|
|
54152
|
+
},
|
|
54153
|
+
interval: 70
|
|
54075
54154
|
});
|
|
54155
|
+
spinner.start();
|
|
54156
|
+
let row = formRow;
|
|
54157
|
+
writeCentered(row, `Directory ${green2("✓")} ${process.cwd()}`);
|
|
54158
|
+
row++;
|
|
54159
|
+
writeCentered(row, `Name ${green2("✓")} ${opts.displayName}`);
|
|
54160
|
+
row++;
|
|
54161
|
+
writeCentered(row, `Mesh ${green2("✓")} ${opts.meshSlug}`);
|
|
54162
|
+
row += 2;
|
|
54163
|
+
let role = opts.existingRole;
|
|
54164
|
+
let groups = opts.existingGroups;
|
|
54165
|
+
let messageMode = opts.existingMessageMode ?? "push";
|
|
54166
|
+
if (role === null) {
|
|
54167
|
+
spinner.stop();
|
|
54168
|
+
const answer = await textInput({ label: "Role", row, placeholder: "optional — press Enter to skip" });
|
|
54169
|
+
if (answer)
|
|
54170
|
+
role = answer;
|
|
54171
|
+
spinner.start();
|
|
54172
|
+
row++;
|
|
54173
|
+
} else {
|
|
54174
|
+
writeCentered(row, `Role ${green2("✓")} ${role}`);
|
|
54175
|
+
row++;
|
|
54176
|
+
}
|
|
54177
|
+
if (groups.length === 0) {
|
|
54178
|
+
spinner.stop();
|
|
54179
|
+
const answer = await textInput({ label: "Groups", row, placeholder: "comma-separated, optional" });
|
|
54180
|
+
if (answer)
|
|
54181
|
+
groups = parseGroupsString(answer);
|
|
54182
|
+
spinner.start();
|
|
54183
|
+
row++;
|
|
54184
|
+
} else {
|
|
54185
|
+
const tags = groups.map((g) => `@${g.name}${g.role ? `:${g.role}` : ""}`).join(", ");
|
|
54186
|
+
writeCentered(row, `Groups ${green2("✓")} ${tags}`);
|
|
54187
|
+
row++;
|
|
54188
|
+
}
|
|
54189
|
+
if (opts.existingMessageMode === null) {
|
|
54190
|
+
row++;
|
|
54191
|
+
spinner.stop();
|
|
54192
|
+
const choice = await menuSelect({
|
|
54193
|
+
title: "Message mode",
|
|
54194
|
+
items: [
|
|
54195
|
+
"Push (real-time, peers can interrupt)",
|
|
54196
|
+
"Inbox (held until you check)",
|
|
54197
|
+
"Off (tools only, no messages)"
|
|
54198
|
+
],
|
|
54199
|
+
row
|
|
54200
|
+
});
|
|
54201
|
+
messageMode = ["push", "inbox", "off"][choice];
|
|
54202
|
+
spinner.start();
|
|
54203
|
+
row += 5;
|
|
54204
|
+
} else {
|
|
54205
|
+
writeCentered(row, `Messages ${green2("✓")} ${messageMode}`);
|
|
54206
|
+
row++;
|
|
54207
|
+
}
|
|
54208
|
+
let skipPermissions = opts.skipPermConfirm;
|
|
54209
|
+
if (!skipPermissions) {
|
|
54210
|
+
row++;
|
|
54211
|
+
spinner.stop();
|
|
54212
|
+
writeCentered(row, dim("Claude will run with --dangerously-skip-permissions,"));
|
|
54213
|
+
writeCentered(row + 1, dim("bypassing ALL permission prompts — not just claudemesh."));
|
|
54214
|
+
row += 3;
|
|
54215
|
+
const confirmed = await confirmPrompt({
|
|
54216
|
+
message: boldOrange("Autonomous mode?"),
|
|
54217
|
+
row,
|
|
54218
|
+
defaultYes: true
|
|
54219
|
+
});
|
|
54220
|
+
if (!confirmed) {
|
|
54221
|
+
exitFullScreen();
|
|
54222
|
+
console.log(" Run without autonomous mode:");
|
|
54223
|
+
console.log(` claude --dangerously-load-development-channels server:claudemesh
|
|
54224
|
+
`);
|
|
54225
|
+
process.exit(0);
|
|
54226
|
+
}
|
|
54227
|
+
skipPermissions = true;
|
|
54228
|
+
spinner.start();
|
|
54229
|
+
}
|
|
54230
|
+
row += 2;
|
|
54231
|
+
writeCentered(row, dim("Launching Claude Code..."));
|
|
54232
|
+
drawBottomBar(`${opts.displayName} on ${opts.meshSlug}`, `mode: ${messageMode}`);
|
|
54233
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
54234
|
+
spinner.stop();
|
|
54235
|
+
exitFullScreen();
|
|
54236
|
+
return { role, groups, messageMode, skipPermissions };
|
|
54076
54237
|
}
|
|
54077
54238
|
function printBanner(name, meshSlug, role, groups, messageMode) {
|
|
54078
54239
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
@@ -54095,44 +54256,6 @@ function printBanner(name, meshSlug, role, groups, messageMode) {
|
|
|
54095
54256
|
console.log(rule);
|
|
54096
54257
|
console.log("");
|
|
54097
54258
|
}
|
|
54098
|
-
async function showLaunchSplash(name, meshSlug, role, groups, messageMode) {
|
|
54099
|
-
if (!process.stdout.isTTY)
|
|
54100
|
-
return;
|
|
54101
|
-
const { rows } = termSize();
|
|
54102
|
-
enterFullScreen();
|
|
54103
|
-
drawTopBar();
|
|
54104
|
-
const logoTop = Math.floor((rows - FRAME_HEIGHT - 10) / 2);
|
|
54105
|
-
const brandRow = logoTop + FRAME_HEIGHT + 1;
|
|
54106
|
-
const subtitleRow = brandRow + 1;
|
|
54107
|
-
const infoRow = subtitleRow + 2;
|
|
54108
|
-
writeCentered(brandRow, boldOrange("claudemesh"));
|
|
54109
|
-
writeCentered(subtitleRow, dim("peer mesh for Claude Code"));
|
|
54110
|
-
const spinner = createSpinner({
|
|
54111
|
-
render(lines) {
|
|
54112
|
-
for (let i = 0;i < lines.length; i++) {
|
|
54113
|
-
writeCentered(logoTop + i, lines[i]);
|
|
54114
|
-
}
|
|
54115
|
-
},
|
|
54116
|
-
interval: 70
|
|
54117
|
-
});
|
|
54118
|
-
spinner.start();
|
|
54119
|
-
const roleSuffix = role ? ` (${role})` : "";
|
|
54120
|
-
const groupStr = groups.length ? " " + groups.map((g) => dim(`@${g.name}`)).join(", ") : "";
|
|
54121
|
-
const steps = [
|
|
54122
|
-
{ label: `Identity`, value: `${name}${roleSuffix}` },
|
|
54123
|
-
{ label: `Mesh`, value: meshSlug },
|
|
54124
|
-
{ label: `Messages`, value: messageMode }
|
|
54125
|
-
];
|
|
54126
|
-
for (let i = 0;i < steps.length; i++) {
|
|
54127
|
-
await new Promise((r) => setTimeout(r, 300));
|
|
54128
|
-
writeCentered(infoRow + i, `${steps[i].label} ${green("✓")} ${steps[i].value}${i === 0 ? groupStr : ""}`);
|
|
54129
|
-
}
|
|
54130
|
-
await new Promise((r) => setTimeout(r, 400));
|
|
54131
|
-
writeCentered(infoRow + steps.length + 1, dim("Launching Claude Code..."));
|
|
54132
|
-
await new Promise((r) => setTimeout(r, 600));
|
|
54133
|
-
spinner.stop();
|
|
54134
|
-
exitFullScreen();
|
|
54135
|
-
}
|
|
54136
54259
|
async function runLaunch(flags, rawArgs) {
|
|
54137
54260
|
const dashIdx = rawArgs.indexOf("--");
|
|
54138
54261
|
const claudePassthrough = dashIdx >= 0 ? rawArgs.slice(dashIdx + 1) : [];
|
|
@@ -54184,7 +54307,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
54184
54307
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
54185
54308
|
const bold3 = (s) => useColor ? `\x1B[1m${s}\x1B[22m` : s;
|
|
54186
54309
|
const dim2 = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
54187
|
-
const
|
|
54310
|
+
const green3 = (s) => useColor ? `\x1B[32m${s}\x1B[39m` : s;
|
|
54188
54311
|
const code = generatePairingCode();
|
|
54189
54312
|
const listener = await startCallbackListener();
|
|
54190
54313
|
const url = `https://claudemesh.com/cli-auth?port=${listener.port}&code=${code}&action=sync`;
|
|
@@ -54243,7 +54366,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
54243
54366
|
saveConfig2(config2);
|
|
54244
54367
|
justSynced = true;
|
|
54245
54368
|
console.log(`
|
|
54246
|
-
${
|
|
54369
|
+
${green3("✓")} Synced ${result.meshes.length} mesh(es): ${result.meshes.map((m) => m.slug).join(", ")}
|
|
54247
54370
|
`);
|
|
54248
54371
|
}
|
|
54249
54372
|
if (config2.meshes.length === 0) {
|
|
@@ -54266,34 +54389,18 @@ async function runLaunch(flags, rawArgs) {
|
|
|
54266
54389
|
let parsedGroups = args.groups ? parseGroupsString(args.groups) : [];
|
|
54267
54390
|
let messageMode = args.messageMode ?? "push";
|
|
54268
54391
|
if (!args.quiet && !justSynced) {
|
|
54269
|
-
|
|
54270
|
-
|
|
54271
|
-
|
|
54272
|
-
|
|
54273
|
-
|
|
54274
|
-
|
|
54275
|
-
|
|
54276
|
-
|
|
54277
|
-
|
|
54278
|
-
|
|
54279
|
-
|
|
54280
|
-
|
|
54281
|
-
Message mode:`);
|
|
54282
|
-
console.log(" 1) Push (real-time, peers can interrupt your work)");
|
|
54283
|
-
console.log(" 2) Inbox (held until you check, notification only)");
|
|
54284
|
-
console.log(" 3) Off (tools only, no messages)");
|
|
54285
|
-
console.log("");
|
|
54286
|
-
const answer = await askLine(" Choice [1]: ");
|
|
54287
|
-
const choice = parseInt(answer || "1", 10);
|
|
54288
|
-
if (choice === 2)
|
|
54289
|
-
messageMode = "inbox";
|
|
54290
|
-
else if (choice === 3)
|
|
54291
|
-
messageMode = "off";
|
|
54292
|
-
else
|
|
54293
|
-
messageMode = "push";
|
|
54294
|
-
}
|
|
54295
|
-
if (role || parsedGroups.length)
|
|
54296
|
-
console.log("");
|
|
54392
|
+
const wizardResult = await runLaunchWizard({
|
|
54393
|
+
displayName,
|
|
54394
|
+
meshSlug: mesh.slug,
|
|
54395
|
+
existingRole: args.role,
|
|
54396
|
+
existingGroups: parsedGroups,
|
|
54397
|
+
existingMessageMode: args.messageMode ?? null,
|
|
54398
|
+
skipPermConfirm: args.skipPermConfirm
|
|
54399
|
+
});
|
|
54400
|
+
role = wizardResult.role;
|
|
54401
|
+
parsedGroups = wizardResult.groups;
|
|
54402
|
+
messageMode = wizardResult.messageMode;
|
|
54403
|
+
args.skipPermConfirm = wizardResult.skipPermissions;
|
|
54297
54404
|
}
|
|
54298
54405
|
const tmpBase = tmpdir();
|
|
54299
54406
|
try {
|
|
@@ -54356,12 +54463,7 @@ async function runLaunch(flags, rawArgs) {
|
|
|
54356
54463
|
writeFileSync4(join4(tmpDir, "config.json"), JSON.stringify(sessionConfig, null, 2) + `
|
|
54357
54464
|
`, "utf-8");
|
|
54358
54465
|
if (!args.quiet) {
|
|
54359
|
-
await showLaunchSplash(displayName, mesh.slug, role, parsedGroups, messageMode);
|
|
54360
54466
|
printBanner(displayName, mesh.slug, role, parsedGroups, messageMode);
|
|
54361
|
-
if (!args.skipPermConfirm) {
|
|
54362
|
-
await confirmPermissions();
|
|
54363
|
-
args.skipPermConfirm = true;
|
|
54364
|
-
}
|
|
54365
54467
|
}
|
|
54366
54468
|
const meshMcpEntries = [];
|
|
54367
54469
|
if (serviceCatalog.length > 0) {
|
|
@@ -54530,7 +54632,7 @@ async function probeBroker(url, timeoutMs = 4000) {
|
|
|
54530
54632
|
async function runStatus() {
|
|
54531
54633
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
54532
54634
|
const dim2 = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
54533
|
-
const
|
|
54635
|
+
const green3 = (s) => useColor ? `\x1B[32m${s}\x1B[39m` : s;
|
|
54534
54636
|
const red2 = (s) => useColor ? `\x1B[31m${s}\x1B[39m` : s;
|
|
54535
54637
|
console.log(`claudemesh status (v${VERSION})`);
|
|
54536
54638
|
console.log("─".repeat(60));
|
|
@@ -54562,7 +54664,7 @@ async function runStatus() {
|
|
|
54562
54664
|
error: probe.error
|
|
54563
54665
|
});
|
|
54564
54666
|
if (probe.ok) {
|
|
54565
|
-
console.log(
|
|
54667
|
+
console.log(green3("reachable"));
|
|
54566
54668
|
} else {
|
|
54567
54669
|
console.log(red2(`unreachable (${probe.error})`));
|
|
54568
54670
|
}
|
|
@@ -54574,7 +54676,7 @@ async function runStatus() {
|
|
|
54574
54676
|
const allOk = results.every((r) => r.reachable);
|
|
54575
54677
|
console.log("");
|
|
54576
54678
|
if (allOk) {
|
|
54577
|
-
console.log(
|
|
54679
|
+
console.log(green3("All meshes reachable."));
|
|
54578
54680
|
process.exit(0);
|
|
54579
54681
|
} else {
|
|
54580
54682
|
const broken = results.filter((r) => !r.reachable).length;
|
|
@@ -54735,7 +54837,7 @@ function checkKeypairs() {
|
|
|
54735
54837
|
async function runDoctor() {
|
|
54736
54838
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
54737
54839
|
const dim2 = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
54738
|
-
const
|
|
54840
|
+
const green3 = (s) => useColor ? `\x1B[32m${s}\x1B[39m` : s;
|
|
54739
54841
|
const red2 = (s) => useColor ? `\x1B[31m${s}\x1B[39m` : s;
|
|
54740
54842
|
console.log(`claudemesh doctor (v${VERSION})`);
|
|
54741
54843
|
console.log("─".repeat(60));
|
|
@@ -54748,7 +54850,7 @@ async function runDoctor() {
|
|
|
54748
54850
|
checkKeypairs()
|
|
54749
54851
|
];
|
|
54750
54852
|
for (const c of checks3) {
|
|
54751
|
-
const mark = c.pass ?
|
|
54853
|
+
const mark = c.pass ? green3("✓") : red2("✗");
|
|
54752
54854
|
const detail = c.detail ? dim2(` (${c.detail})`) : "";
|
|
54753
54855
|
console.log(`${mark} ${c.name}${detail}`);
|
|
54754
54856
|
if (!c.pass && c.fix) {
|
|
@@ -54758,7 +54860,7 @@ async function runDoctor() {
|
|
|
54758
54860
|
const failing = checks3.filter((c) => !c.pass);
|
|
54759
54861
|
console.log("");
|
|
54760
54862
|
if (failing.length === 0) {
|
|
54761
|
-
console.log(
|
|
54863
|
+
console.log(green3("All checks passed."));
|
|
54762
54864
|
process.exit(0);
|
|
54763
54865
|
} else {
|
|
54764
54866
|
console.log(red2(`${failing.length} check(s) failed.`));
|
|
@@ -54799,6 +54901,7 @@ async function runWelcome() {
|
|
|
54799
54901
|
const { rows } = termSize();
|
|
54800
54902
|
enterFullScreen();
|
|
54801
54903
|
drawTopBar();
|
|
54904
|
+
drawBottomBar("↑↓ navigate ⏎ select ctrl-c quit", "claudemesh.com");
|
|
54802
54905
|
const logoTop = Math.floor((rows - FRAME_HEIGHT - 10) / 2);
|
|
54803
54906
|
const brandRow = logoTop + FRAME_HEIGHT + 1;
|
|
54804
54907
|
const subtitleRow = brandRow + 1;
|
|
@@ -54830,14 +54933,14 @@ async function runWelcome() {
|
|
|
54830
54933
|
});
|
|
54831
54934
|
exitFullScreen();
|
|
54832
54935
|
if (choice === 0) {
|
|
54833
|
-
console.log(
|
|
54936
|
+
console.log(green2("$") + ` claudemesh install
|
|
54834
54937
|
`);
|
|
54835
54938
|
}
|
|
54836
54939
|
break;
|
|
54837
54940
|
}
|
|
54838
54941
|
case "no-meshes": {
|
|
54839
|
-
writeCentered(contentRow,
|
|
54840
|
-
writeCentered(contentRow + 2, dim("MCP server ") +
|
|
54942
|
+
writeCentered(contentRow, green2("✓") + " MCP registered. Now join a mesh.");
|
|
54943
|
+
writeCentered(contentRow + 2, dim("MCP server ") + green2("✓") + dim(" registered"));
|
|
54841
54944
|
writeCentered(contentRow + 3, dim("Mesh ") + yellow("○") + dim(" none joined"));
|
|
54842
54945
|
menuRow = contentRow + 5;
|
|
54843
54946
|
spinner.stop();
|
|
@@ -54852,11 +54955,11 @@ async function runWelcome() {
|
|
|
54852
54955
|
});
|
|
54853
54956
|
exitFullScreen();
|
|
54854
54957
|
if (choice === 0) {
|
|
54855
|
-
console.log(
|
|
54958
|
+
console.log(green2("$") + ` claudemesh join https://claudemesh.com/join/<token>
|
|
54856
54959
|
`);
|
|
54857
54960
|
console.log(dim(" Don't have an invite? Create one at ") + bold2("https://claudemesh.com") + dim(" or ask a mesh owner."));
|
|
54858
54961
|
} else if (choice === 1) {
|
|
54859
|
-
console.log(
|
|
54962
|
+
console.log(green2("$") + ` claudemesh create
|
|
54860
54963
|
`);
|
|
54861
54964
|
}
|
|
54862
54965
|
break;
|
|
@@ -54864,8 +54967,8 @@ async function runWelcome() {
|
|
|
54864
54967
|
case "ready": {
|
|
54865
54968
|
const cfg = loadConfig();
|
|
54866
54969
|
const meshNames = cfg.meshes.map((m) => m.slug).join(", ");
|
|
54867
|
-
writeCentered(contentRow,
|
|
54868
|
-
writeCentered(contentRow + 1,
|
|
54970
|
+
writeCentered(contentRow, green2("✓") + " MCP registered");
|
|
54971
|
+
writeCentered(contentRow + 1, green2("✓") + ` ${cfg.meshes.length} mesh(es): ${meshNames}`);
|
|
54869
54972
|
writeCentered(contentRow + 2, "");
|
|
54870
54973
|
writeCentered(contentRow + 3, bold2("Ready to launch."));
|
|
54871
54974
|
menuRow = contentRow + 5;
|
|
@@ -54884,19 +54987,19 @@ async function runWelcome() {
|
|
|
54884
54987
|
exitFullScreen();
|
|
54885
54988
|
switch (choice) {
|
|
54886
54989
|
case 0:
|
|
54887
|
-
console.log(
|
|
54990
|
+
console.log(green2("$") + ` claudemesh launch
|
|
54888
54991
|
`);
|
|
54889
54992
|
break;
|
|
54890
54993
|
case 1:
|
|
54891
|
-
console.log(
|
|
54994
|
+
console.log(green2("$") + ` claudemesh peers
|
|
54892
54995
|
`);
|
|
54893
54996
|
break;
|
|
54894
54997
|
case 2:
|
|
54895
|
-
console.log(
|
|
54998
|
+
console.log(green2("$") + ` claudemesh status
|
|
54896
54999
|
`);
|
|
54897
55000
|
break;
|
|
54898
55001
|
case 3:
|
|
54899
|
-
console.log(
|
|
55002
|
+
console.log(green2("$") + ` claudemesh doctor
|
|
54900
55003
|
`);
|
|
54901
55004
|
break;
|
|
54902
55005
|
}
|
|
@@ -54913,7 +55016,7 @@ async function runWelcome() {
|
|
|
54913
55016
|
});
|
|
54914
55017
|
exitFullScreen();
|
|
54915
55018
|
if (choice === 0) {
|
|
54916
|
-
console.log(
|
|
55019
|
+
console.log(green2("$") + ` claudemesh doctor
|
|
54917
55020
|
`);
|
|
54918
55021
|
}
|
|
54919
55022
|
break;
|
|
@@ -54984,7 +55087,7 @@ async function runPeers(flags) {
|
|
|
54984
55087
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
54985
55088
|
const dim2 = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
54986
55089
|
const bold3 = (s) => useColor ? `\x1B[1m${s}\x1B[22m` : s;
|
|
54987
|
-
const
|
|
55090
|
+
const green3 = (s) => useColor ? `\x1B[32m${s}\x1B[39m` : s;
|
|
54988
55091
|
const yellow2 = (s) => useColor ? `\x1B[33m${s}\x1B[39m` : s;
|
|
54989
55092
|
await withMesh({ meshSlug: flags.mesh ?? null }, async (client2, mesh) => {
|
|
54990
55093
|
const peers = await client2.listPeers();
|
|
@@ -55000,7 +55103,7 @@ async function runPeers(flags) {
|
|
|
55000
55103
|
console.log("");
|
|
55001
55104
|
for (const p of peers) {
|
|
55002
55105
|
const groups = p.groups.length ? " [" + p.groups.map((g) => `@${g.name}${g.role ? `:${g.role}` : ""}`).join(", ") + "]" : "";
|
|
55003
|
-
const statusIcon = p.status === "working" ? yellow2("●") :
|
|
55106
|
+
const statusIcon = p.status === "working" ? yellow2("●") : green3("●");
|
|
55004
55107
|
const name = bold3(p.displayName);
|
|
55005
55108
|
const meta2 = [];
|
|
55006
55109
|
if (p.peerType)
|
|
@@ -55488,7 +55591,7 @@ init_keypair();
|
|
|
55488
55591
|
async function runSync(args) {
|
|
55489
55592
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
55490
55593
|
const dim2 = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
55491
|
-
const
|
|
55594
|
+
const green3 = (s) => useColor ? `\x1B[32m${s}\x1B[39m` : s;
|
|
55492
55595
|
const config2 = loadConfig();
|
|
55493
55596
|
const code = generatePairingCode();
|
|
55494
55597
|
const listener = await startCallbackListener();
|
|
@@ -55539,7 +55642,7 @@ async function runSync(args) {
|
|
|
55539
55642
|
config2.accountId = result.account_id;
|
|
55540
55643
|
saveConfig(config2);
|
|
55541
55644
|
if (added > 0) {
|
|
55542
|
-
console.log(
|
|
55645
|
+
console.log(green3(`✓ Added ${added} new mesh(es)`));
|
|
55543
55646
|
} else {
|
|
55544
55647
|
console.log(`Already up to date (${config2.meshes.length} meshes)`);
|
|
55545
55648
|
}
|
|
@@ -55550,7 +55653,7 @@ init_config();
|
|
|
55550
55653
|
async function runProfile(flags) {
|
|
55551
55654
|
const useColor = !process.env.NO_COLOR && process.env.TERM !== "dumb" && process.stdout.isTTY;
|
|
55552
55655
|
const dim2 = (s) => useColor ? `\x1B[2m${s}\x1B[22m` : s;
|
|
55553
|
-
const
|
|
55656
|
+
const green3 = (s) => useColor ? `\x1B[32m${s}\x1B[39m` : s;
|
|
55554
55657
|
const config2 = loadConfig();
|
|
55555
55658
|
if (config2.meshes.length === 0) {
|
|
55556
55659
|
console.error("No meshes joined. Run `claudemesh join <url>` first.");
|
|
@@ -55590,7 +55693,7 @@ async function runProfile(flags) {
|
|
|
55590
55693
|
if (flags.json) {
|
|
55591
55694
|
console.log(JSON.stringify(result, null, 2));
|
|
55592
55695
|
} else if (result.ok) {
|
|
55593
|
-
console.log(
|
|
55696
|
+
console.log(green3("✓ Profile updated"));
|
|
55594
55697
|
const member = result.member;
|
|
55595
55698
|
printProfile(member, dim2);
|
|
55596
55699
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudemesh-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.5",
|
|
4
4
|
"description": "Claude Code MCP client for claudemesh — peer mesh messaging between Claude sessions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude-code",
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"prettier": "3.6.2",
|
|
49
49
|
"typescript": "5.9.3",
|
|
50
50
|
"vitest": "4.0.14",
|
|
51
|
-
"@turbostarter/
|
|
52
|
-
"@turbostarter/eslint-config": "0.1.0",
|
|
51
|
+
"@turbostarter/tsconfig": "0.1.0",
|
|
53
52
|
"@turbostarter/vitest-config": "0.1.0",
|
|
54
|
-
"@turbostarter/
|
|
53
|
+
"@turbostarter/prettier-config": "0.1.0",
|
|
54
|
+
"@turbostarter/eslint-config": "0.1.0"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "bun build src/index.ts --target=node --outfile dist/index.js --banner \"#!/usr/bin/env node\" && chmod +x dist/index.js",
|