claudemesh-cli 1.8.0 → 1.9.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 +3 -1
- package/dist/entrypoints/cli.js +206 -20
- package/dist/entrypoints/cli.js.map +10 -9
- package/dist/entrypoints/mcp.js +25 -4
- package/dist/entrypoints/mcp.js.map +4 -4
- package/package.json +1 -1
- package/skills/claudemesh/SKILL.md +71 -1
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Peer mesh for Claude Code sessions. Connect multiple Claude Code instances into a shared mesh with real-time messaging, shared state, memory, file sharing, vector store, scheduled jobs, and more — all driven from the `claudemesh` CLI. The MCP server is a tool-less push-pipe that delivers inbound peer messages to Claude as `<channel>` interrupts; everything else lives behind CLI verbs that Claude learns from the auto-installed `claudemesh` skill.
|
|
4
4
|
|
|
5
|
-
> **What's new in 1.
|
|
5
|
+
> **What's new in 1.9.x:** topic threading + multi-session reliability fixes. `claudemesh topic post <topic> <msg> --reply-to <id>` threads a reply onto a previous topic message (full id or 8+ char prefix); `topic tail` renders `↳ in reply to <name>: "<snippet>"` above replies and shows a copyable `#xxxxxxxx` short id on every row. `<channel>` MCP attrs now carry `from_member_id`, `from_pubkey` (stable), `from_session_pubkey` (ephemeral), `message_id`, `topic`, `reply_to_id` — everything the recipient needs to reply directly. Broker fixes (v0.3.2): replies to a stale session pubkey now resolve to the owning member's live session instead of bouncing with "not online", and broadcast `*` no longer loopbacks decrypt-fail warnings to the sender's sibling sessions.
|
|
6
|
+
>
|
|
7
|
+
> **What was new in 1.8.0:** per-topic end-to-end encryption (v0.3.0 phase 3, CLI side). `claudemesh topic post <topic> <msg>` encrypts the body with `crypto_secretbox` under the topic's symmetric key — broker stores ciphertext only. `claudemesh topic tail` now decrypts v2 messages on render and runs a background re-seal loop every 30s, so new topic joiners get their sealed keys without manual action. `topic-key` cache is process-only — kill the CLI, the key forgets. Web dashboard reads v1 plaintext for now (phase 3.5 brings browser-side identity).
|
|
6
8
|
>
|
|
7
9
|
> **What was new in 1.7.0:** terminal parity for the v1.6.x server features. New verbs: `claudemesh topic tail` (live SSE message stream — Ctrl-C to exit), `claudemesh notification list` (recent `@you` mentions across topics), `claudemesh member list` (mesh roster with online dots, distinct from `peer list`'s live-session view). Each command auto-mints a 5-minute read-only apikey via the WebSocket and revokes it on exit, so no token plumbing is needed.
|
|
8
10
|
>
|
package/dist/entrypoints/cli.js
CHANGED
|
@@ -88,7 +88,7 @@ __export(exports_urls, {
|
|
|
88
88
|
VERSION: () => VERSION,
|
|
89
89
|
URLS: () => URLS
|
|
90
90
|
});
|
|
91
|
-
var URLS, VERSION = "1.
|
|
91
|
+
var URLS, VERSION = "1.9.3", env;
|
|
92
92
|
var init_urls = __esm(() => {
|
|
93
93
|
URLS = {
|
|
94
94
|
BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
|
|
@@ -2779,6 +2779,11 @@ class BrokerClient {
|
|
|
2779
2779
|
messageId: String(msg.messageId ?? ""),
|
|
2780
2780
|
meshId: String(msg.meshId ?? ""),
|
|
2781
2781
|
senderPubkey,
|
|
2782
|
+
...msg.senderMemberPubkey ? { senderMemberPubkey: String(msg.senderMemberPubkey) } : {},
|
|
2783
|
+
...msg.senderMemberId ? { senderMemberId: String(msg.senderMemberId) } : {},
|
|
2784
|
+
...msg.senderName ? { senderName: String(msg.senderName) } : {},
|
|
2785
|
+
...msg.topic ? { topic: String(msg.topic) } : {},
|
|
2786
|
+
...msg.replyToId ? { replyToId: String(msg.replyToId) } : {},
|
|
2782
2787
|
priority: msg.priority ?? "next",
|
|
2783
2788
|
nonce,
|
|
2784
2789
|
ciphertext,
|
|
@@ -7078,6 +7083,61 @@ var init_recall = __esm(() => {
|
|
|
7078
7083
|
init_exit_codes();
|
|
7079
7084
|
});
|
|
7080
7085
|
|
|
7086
|
+
// src/cli/validators.ts
|
|
7087
|
+
function validateMessageId(input) {
|
|
7088
|
+
if (!input) {
|
|
7089
|
+
return {
|
|
7090
|
+
ok: false,
|
|
7091
|
+
code: "missing",
|
|
7092
|
+
reason: "message id is required",
|
|
7093
|
+
expected: "32-char base62 id, or ≥8-char prefix"
|
|
7094
|
+
};
|
|
7095
|
+
}
|
|
7096
|
+
if (input.length < 8) {
|
|
7097
|
+
return {
|
|
7098
|
+
ok: false,
|
|
7099
|
+
code: "too_short",
|
|
7100
|
+
reason: `id is ${input.length} chars, needs ≥8`,
|
|
7101
|
+
expected: "8+ chars (paste from a previous send/post output)"
|
|
7102
|
+
};
|
|
7103
|
+
}
|
|
7104
|
+
if (input.length > 32) {
|
|
7105
|
+
return {
|
|
7106
|
+
ok: false,
|
|
7107
|
+
code: "too_long",
|
|
7108
|
+
reason: `id is ${input.length} chars, max 32`,
|
|
7109
|
+
expected: "trim trailing characters"
|
|
7110
|
+
};
|
|
7111
|
+
}
|
|
7112
|
+
if (!BASE62_RE.test(input)) {
|
|
7113
|
+
return {
|
|
7114
|
+
ok: false,
|
|
7115
|
+
code: "bad_charset",
|
|
7116
|
+
reason: "id contains characters outside [A-Za-z0-9]",
|
|
7117
|
+
expected: "base62 only"
|
|
7118
|
+
};
|
|
7119
|
+
}
|
|
7120
|
+
return { ok: true, value: { value: input, isPrefix: input.length < 32 } };
|
|
7121
|
+
}
|
|
7122
|
+
function renderValidationError(args, write = (s) => process.stderr.write(s)) {
|
|
7123
|
+
write(` \x1B[31m✘\x1B[0m ${args.verb} ${args.input}
|
|
7124
|
+
`);
|
|
7125
|
+
write(` ${args.result.reason}.
|
|
7126
|
+
`);
|
|
7127
|
+
if (args.result.expected) {
|
|
7128
|
+
write(` expected: ${args.result.expected}
|
|
7129
|
+
`);
|
|
7130
|
+
}
|
|
7131
|
+
if (args.nearest) {
|
|
7132
|
+
write(` did you mean: \x1B[36m${args.nearest}\x1B[0m
|
|
7133
|
+
`);
|
|
7134
|
+
}
|
|
7135
|
+
}
|
|
7136
|
+
var BASE62_RE;
|
|
7137
|
+
var init_validators = __esm(() => {
|
|
7138
|
+
BASE62_RE = /^[A-Za-z0-9]+$/;
|
|
7139
|
+
});
|
|
7140
|
+
|
|
7081
7141
|
// src/commands/broker-actions.ts
|
|
7082
7142
|
var exports_broker_actions = {};
|
|
7083
7143
|
__export(exports_broker_actions, {
|
|
@@ -7241,17 +7301,44 @@ async function runForget(id, opts) {
|
|
|
7241
7301
|
return EXIT.SUCCESS;
|
|
7242
7302
|
}
|
|
7243
7303
|
async function runMsgStatus(id, opts) {
|
|
7244
|
-
|
|
7245
|
-
|
|
7304
|
+
const v = validateMessageId(id);
|
|
7305
|
+
if (!v.ok) {
|
|
7306
|
+
if (opts.json) {
|
|
7307
|
+
console.log(JSON.stringify({
|
|
7308
|
+
ok: false,
|
|
7309
|
+
error: "invalid_argument",
|
|
7310
|
+
field: "messageId",
|
|
7311
|
+
code: v.code,
|
|
7312
|
+
reason: v.reason,
|
|
7313
|
+
expected: v.expected
|
|
7314
|
+
}));
|
|
7315
|
+
} else {
|
|
7316
|
+
renderValidationError({
|
|
7317
|
+
verb: "msg-status",
|
|
7318
|
+
input: id ?? "(missing)",
|
|
7319
|
+
result: v
|
|
7320
|
+
});
|
|
7321
|
+
}
|
|
7246
7322
|
return EXIT.INVALID_ARGS;
|
|
7247
7323
|
}
|
|
7324
|
+
const lookupId = v.value.value;
|
|
7248
7325
|
return await withMesh({ meshSlug: opts.mesh ?? null }, async (client) => {
|
|
7249
|
-
const result = await client.messageStatus(
|
|
7326
|
+
const result = await client.messageStatus(lookupId);
|
|
7250
7327
|
if (!result) {
|
|
7251
|
-
if (opts.json)
|
|
7252
|
-
console.log(JSON.stringify({
|
|
7253
|
-
|
|
7254
|
-
|
|
7328
|
+
if (opts.json) {
|
|
7329
|
+
console.log(JSON.stringify({
|
|
7330
|
+
ok: false,
|
|
7331
|
+
error: "not_found",
|
|
7332
|
+
id: lookupId,
|
|
7333
|
+
isPrefix: v.value.isPrefix
|
|
7334
|
+
}));
|
|
7335
|
+
} else {
|
|
7336
|
+
const hint = v.value.isPrefix ? ` no message id starts with ${dim('"' + lookupId + '"')} in this mesh.
|
|
7337
|
+
try: claudemesh msg-status <full-32-char-id>` : ` message ${dim(lookupId.slice(0, 12) + "…")} not in queue (already drained, expired, or never sent in this mesh).`;
|
|
7338
|
+
render.err(`message not found`);
|
|
7339
|
+
process.stderr.write(hint + `
|
|
7340
|
+
`);
|
|
7341
|
+
}
|
|
7255
7342
|
return EXIT.NOT_FOUND;
|
|
7256
7343
|
}
|
|
7257
7344
|
if (opts.json) {
|
|
@@ -7383,6 +7470,7 @@ var init_broker_actions = __esm(() => {
|
|
|
7383
7470
|
init_render();
|
|
7384
7471
|
init_styles();
|
|
7385
7472
|
init_exit_codes();
|
|
7473
|
+
init_validators();
|
|
7386
7474
|
});
|
|
7387
7475
|
|
|
7388
7476
|
// src/commands/remind.ts
|
|
@@ -11798,6 +11886,17 @@ var exports_topic_tail = {};
|
|
|
11798
11886
|
__export(exports_topic_tail, {
|
|
11799
11887
|
runTopicTail: () => runTopicTail
|
|
11800
11888
|
});
|
|
11889
|
+
function rememberRendered(cache2, m, text) {
|
|
11890
|
+
cache2.set(m.id, {
|
|
11891
|
+
name: m.senderName || m.senderPubkey.slice(0, 8),
|
|
11892
|
+
snippet: text.replace(/\s+/g, " ").slice(0, 60)
|
|
11893
|
+
});
|
|
11894
|
+
if (cache2.size > RECENT_CACHE_MAX) {
|
|
11895
|
+
const firstKey = cache2.keys().next().value;
|
|
11896
|
+
if (firstKey)
|
|
11897
|
+
cache2.delete(firstKey);
|
|
11898
|
+
}
|
|
11899
|
+
}
|
|
11801
11900
|
function decodeV1(b64) {
|
|
11802
11901
|
try {
|
|
11803
11902
|
return Buffer.from(b64, "base64").toString("utf-8");
|
|
@@ -11824,15 +11923,24 @@ function fmtTime(iso) {
|
|
|
11824
11923
|
return iso;
|
|
11825
11924
|
}
|
|
11826
11925
|
}
|
|
11827
|
-
async function printMessage(m, topicKey, json) {
|
|
11926
|
+
async function printMessage(m, topicKey, json, cache2) {
|
|
11828
11927
|
const text = await decryptForRender(m, topicKey);
|
|
11829
11928
|
if (json) {
|
|
11830
11929
|
console.log(JSON.stringify({ ...m, message: text }));
|
|
11930
|
+
rememberRendered(cache2, m, text);
|
|
11831
11931
|
return;
|
|
11832
11932
|
}
|
|
11833
11933
|
const v2Marker = (m.bodyVersion ?? 1) === 2 ? dim("\uD83D\uDD12 ") : "";
|
|
11834
|
-
|
|
11934
|
+
if (m.replyToId) {
|
|
11935
|
+
const parent = cache2.get(m.replyToId);
|
|
11936
|
+
const ref = parent ? `${parent.name}: "${parent.snippet}${parent.snippet.length === 60 ? "…" : ""}"` : `${m.replyToId.slice(0, 8)}…`;
|
|
11937
|
+
process.stdout.write(` ${dim("↳ in reply to " + ref)}
|
|
11938
|
+
`);
|
|
11939
|
+
}
|
|
11940
|
+
const idTag = dim(`#${m.id.slice(0, 8)}`);
|
|
11941
|
+
process.stdout.write(` ${dim(fmtTime(m.createdAt))} ${bold(m.senderName || m.senderPubkey.slice(0, 8))} ${idTag} ${v2Marker}${text}
|
|
11835
11942
|
`);
|
|
11943
|
+
rememberRendered(cache2, m, text);
|
|
11836
11944
|
}
|
|
11837
11945
|
async function* readSseStream(reader) {
|
|
11838
11946
|
const decoder = new TextDecoder;
|
|
@@ -11891,6 +11999,7 @@ async function runTopicTail(name, flags) {
|
|
|
11891
11999
|
topicName: cleanName
|
|
11892
12000
|
});
|
|
11893
12001
|
const topicKey = keyResult.ok ? keyResult.topicKey ?? null : null;
|
|
12002
|
+
const snippetCache = new Map;
|
|
11894
12003
|
let resealTimer = null;
|
|
11895
12004
|
if (topicKey) {
|
|
11896
12005
|
const reseal = async () => {
|
|
@@ -11943,7 +12052,7 @@ async function runTopicTail(name, flags) {
|
|
|
11943
12052
|
render.section(`${clay("#" + cleanName)} on ${dim(meshSlug)} — backfill ${history.messages.length}, then live`);
|
|
11944
12053
|
}
|
|
11945
12054
|
for (const m of history.messages.slice().reverse()) {
|
|
11946
|
-
await printMessage(m, topicKey, flags.json ?? false);
|
|
12055
|
+
await printMessage(m, topicKey, flags.json ?? false, snippetCache);
|
|
11947
12056
|
}
|
|
11948
12057
|
} catch (err) {
|
|
11949
12058
|
render.warn(`backfill failed: ${err.message}`);
|
|
@@ -11982,7 +12091,7 @@ async function runTopicTail(name, flags) {
|
|
|
11982
12091
|
if (ev.event === "message") {
|
|
11983
12092
|
try {
|
|
11984
12093
|
const m = JSON.parse(ev.data);
|
|
11985
|
-
await printMessage(m, topicKey, flags.json ?? false);
|
|
12094
|
+
await printMessage(m, topicKey, flags.json ?? false, snippetCache);
|
|
11986
12095
|
} catch {}
|
|
11987
12096
|
}
|
|
11988
12097
|
}
|
|
@@ -12000,6 +12109,7 @@ async function runTopicTail(name, flags) {
|
|
|
12000
12109
|
}
|
|
12001
12110
|
});
|
|
12002
12111
|
}
|
|
12112
|
+
var RECENT_CACHE_MAX = 256;
|
|
12003
12113
|
var init_topic_tail = __esm(() => {
|
|
12004
12114
|
init_urls();
|
|
12005
12115
|
init_with_rest_key();
|
|
@@ -12060,6 +12170,27 @@ async function runTopicPost(topicName, message, flags) {
|
|
|
12060
12170
|
return EXIT.INTERNAL_ERROR;
|
|
12061
12171
|
}
|
|
12062
12172
|
}
|
|
12173
|
+
let replyToId;
|
|
12174
|
+
if (flags.replyTo) {
|
|
12175
|
+
if (flags.replyTo.length >= 16) {
|
|
12176
|
+
replyToId = flags.replyTo;
|
|
12177
|
+
} else if (flags.replyTo.length >= 6) {
|
|
12178
|
+
const recent = await request({
|
|
12179
|
+
path: `/api/v1/topics/${encodeURIComponent(cleanName)}/messages?limit=200`,
|
|
12180
|
+
method: "GET",
|
|
12181
|
+
token: secret
|
|
12182
|
+
});
|
|
12183
|
+
const hit = recent.messages?.find((r) => r.id.startsWith(flags.replyTo));
|
|
12184
|
+
if (!hit) {
|
|
12185
|
+
render.err(`--reply-to ${flags.replyTo}: no recent message id starts with that prefix`);
|
|
12186
|
+
return EXIT.INVALID_ARGS;
|
|
12187
|
+
}
|
|
12188
|
+
replyToId = hit.id;
|
|
12189
|
+
} else {
|
|
12190
|
+
render.err("--reply-to needs at least 6 characters of the message id");
|
|
12191
|
+
return EXIT.INVALID_ARGS;
|
|
12192
|
+
}
|
|
12193
|
+
}
|
|
12063
12194
|
const result = await request({
|
|
12064
12195
|
path: "/api/v1/messages",
|
|
12065
12196
|
method: "POST",
|
|
@@ -12069,7 +12200,8 @@ async function runTopicPost(topicName, message, flags) {
|
|
|
12069
12200
|
ciphertext,
|
|
12070
12201
|
nonce,
|
|
12071
12202
|
bodyVersion,
|
|
12072
|
-
...mentions.length > 0 ? { mentions } : {}
|
|
12203
|
+
...mentions.length > 0 ? { mentions } : {},
|
|
12204
|
+
...replyToId ? { replyToId } : {}
|
|
12073
12205
|
}
|
|
12074
12206
|
});
|
|
12075
12207
|
if (flags.json) {
|
|
@@ -12077,7 +12209,8 @@ async function runTopicPost(topicName, message, flags) {
|
|
|
12077
12209
|
return EXIT.SUCCESS;
|
|
12078
12210
|
}
|
|
12079
12211
|
const versionTag = bodyVersion === 2 ? green("\uD83D\uDD12 v2") : dim("v1");
|
|
12080
|
-
|
|
12212
|
+
const replyTag = result.replyToId ? ` ${dim("↳ " + result.replyToId.slice(0, 8))}` : "";
|
|
12213
|
+
render.ok("posted", `${clay("#" + cleanName)} ${versionTag}${replyTag} ${dim(`(${result.notifications} mentions)`)}`);
|
|
12081
12214
|
return EXIT.SUCCESS;
|
|
12082
12215
|
});
|
|
12083
12216
|
}
|
|
@@ -12445,7 +12578,16 @@ async function startMcpServer() {
|
|
|
12445
12578
|
You are "${myName}"${myRole ? ` (${myRole})` : ""} — a peer in the claudemesh network. Your groups: ${myGroups}. You are one of several Claude Code sessions connected to the same mesh. No orchestrator exists — peers are equals. Your identity comes from your name and group roles, not from a central authority.
|
|
12446
12579
|
|
|
12447
12580
|
## Responding to messages
|
|
12448
|
-
When you receive a <channel source="claudemesh" ...> message, RESPOND IMMEDIATELY. Pause your current task, reply via send_message
|
|
12581
|
+
When you receive a <channel source="claudemesh" ...> message, RESPOND IMMEDIATELY. Pause your current task, reply via send_message (or \`claudemesh topic post --reply-to <message_id>\` for topic threads), then resume. Stay in character per your system prompt. Do not ignore low-priority messages — acknowledge them briefly even if you defer action.
|
|
12582
|
+
|
|
12583
|
+
The channel attributes carry everything you need to reply — no extra lookups:
|
|
12584
|
+
- \`from_name\` — sender display name. Use as the \`to\` arg when replying to a DM.
|
|
12585
|
+
- \`from_pubkey\` / \`from_member_id\` — stable ids. Use \`from_member_id\` if the sender's display name might change.
|
|
12586
|
+
- \`mesh_slug\` — pass via \`--mesh\` if your default mesh differs.
|
|
12587
|
+
- \`priority\` — \`now\` / \`next\` / \`low\`.
|
|
12588
|
+
- \`message_id\` — id of THIS message. To thread a reply onto it in a topic, run \`claudemesh topic post <topic> "<text>" --reply-to <message_id>\`.
|
|
12589
|
+
- \`topic\` — set when the message arrived through a topic (vs DM). Reply in the same topic.
|
|
12590
|
+
- \`reply_to_id\` — set when the incoming message is itself a reply. Render thread context if you re-narrate.
|
|
12449
12591
|
|
|
12450
12592
|
If the channel meta contains \`subtype: reminder\`, this is a scheduled reminder you set for yourself — act on it immediately (no reply needed).
|
|
12451
12593
|
|
|
@@ -12805,20 +12947,27 @@ ${manifest.allowed_tools.map((t) => ` - ${t}`).join(`
|
|
|
12805
12947
|
const prioBadge = msg.priority === "now" ? "[URGENT] " : msg.priority === "low" ? "[low] " : "";
|
|
12806
12948
|
const kindBadge = msg.kind === "broadcast" ? " (broadcast)" : "";
|
|
12807
12949
|
const content = `${prioBadge}${fromName}${kindBadge}: ${body}`;
|
|
12950
|
+
const fromMemberPubkey = msg.senderMemberPubkey ?? fromPubkey;
|
|
12808
12951
|
try {
|
|
12809
12952
|
await server.notification({
|
|
12810
12953
|
method: "notifications/claude/channel",
|
|
12811
12954
|
params: {
|
|
12812
12955
|
content,
|
|
12813
12956
|
meta: {
|
|
12814
|
-
from_id:
|
|
12957
|
+
from_id: fromMemberPubkey,
|
|
12958
|
+
from_pubkey: fromMemberPubkey,
|
|
12959
|
+
from_session_pubkey: fromPubkey,
|
|
12815
12960
|
from_name: fromName,
|
|
12961
|
+
...msg.senderMemberId ? { from_member_id: msg.senderMemberId } : {},
|
|
12816
12962
|
mesh_slug: client.meshSlug,
|
|
12817
12963
|
mesh_id: client.meshId,
|
|
12818
12964
|
priority: msg.priority,
|
|
12819
12965
|
sent_at: msg.createdAt,
|
|
12820
12966
|
delivered_at: msg.receivedAt,
|
|
12821
12967
|
kind: msg.kind,
|
|
12968
|
+
message_id: msg.messageId,
|
|
12969
|
+
...msg.topic ? { topic: msg.topic } : {},
|
|
12970
|
+
...msg.replyToId ? { reply_to_id: msg.replyToId } : {},
|
|
12822
12971
|
...msg.subtype ? { subtype: msg.subtype } : {}
|
|
12823
12972
|
}
|
|
12824
12973
|
}
|
|
@@ -13682,6 +13831,7 @@ async function gate(ctx, opts) {
|
|
|
13682
13831
|
}
|
|
13683
13832
|
|
|
13684
13833
|
// src/entrypoints/cli.ts
|
|
13834
|
+
init_styles();
|
|
13685
13835
|
installSignalHandlers();
|
|
13686
13836
|
installErrorHandlers();
|
|
13687
13837
|
var { command, positionals, flags } = parseArgv(process.argv);
|
|
@@ -13772,7 +13922,7 @@ Topic (conversation scope, v0.2.0)
|
|
|
13772
13922
|
claudemesh topic history <t> fetch message history [--limit --before]
|
|
13773
13923
|
claudemesh topic read <topic> mark all as read
|
|
13774
13924
|
claudemesh topic tail <topic> live SSE tail [--limit --forward-only]
|
|
13775
|
-
claudemesh topic post <t> <msg> encrypted REST post (v0.3.0 v2)
|
|
13925
|
+
claudemesh topic post <t> <msg> encrypted REST post (v0.3.0 v2) [--reply-to <id>]
|
|
13776
13926
|
claudemesh send "#topic" "msg" send to a topic (WS path, v1 plaintext)
|
|
13777
13927
|
claudemesh member list mesh roster with online state [--online]
|
|
13778
13928
|
claudemesh notification list recent @-mentions of you [--since <ISO>]
|
|
@@ -13843,9 +13993,44 @@ Flags
|
|
|
13843
13993
|
-y, --yes skip confirmations (= --approval-mode yolo)
|
|
13844
13994
|
-q, --quiet suppress non-essential output
|
|
13845
13995
|
`;
|
|
13996
|
+
function colorizeHelp(raw) {
|
|
13997
|
+
const lines = raw.split(`
|
|
13998
|
+
`);
|
|
13999
|
+
const SECTION_HEADER_RE = /^([A-Z][A-Za-z0-9 /+-]*?)(\s*\(.*\))?$/;
|
|
14000
|
+
const VERB_ROW_RE = /^(\s{2})(claudemesh[^\s]*(?:\s+[^\s]+)*?)(\s{2,})(.*)$/;
|
|
14001
|
+
const ALIAS_RE = /(\(alias[^)]*\))/g;
|
|
14002
|
+
const out = [];
|
|
14003
|
+
for (const line of lines) {
|
|
14004
|
+
if (line.startsWith("claudemesh —")) {
|
|
14005
|
+
out.push(orange(line));
|
|
14006
|
+
continue;
|
|
14007
|
+
}
|
|
14008
|
+
if (line.trim() === "") {
|
|
14009
|
+
out.push(line);
|
|
14010
|
+
continue;
|
|
14011
|
+
}
|
|
14012
|
+
if (!line.startsWith(" ") && SECTION_HEADER_RE.test(line)) {
|
|
14013
|
+
const m = line.match(SECTION_HEADER_RE);
|
|
14014
|
+
const head = bold(clay(m[1]));
|
|
14015
|
+
const meta = m[2] ? dim(m[2]) : "";
|
|
14016
|
+
out.push(head + meta);
|
|
14017
|
+
continue;
|
|
14018
|
+
}
|
|
14019
|
+
const verbMatch = line.match(VERB_ROW_RE);
|
|
14020
|
+
if (verbMatch) {
|
|
14021
|
+
const [, indent, syntax, gap, rest] = verbMatch;
|
|
14022
|
+
const dimmedRest = rest.replace(ALIAS_RE, (m) => dim(m));
|
|
14023
|
+
out.push(`${indent}${cyan(syntax)}${gap}${dimmedRest}`);
|
|
14024
|
+
continue;
|
|
14025
|
+
}
|
|
14026
|
+
out.push(line);
|
|
14027
|
+
}
|
|
14028
|
+
return out.join(`
|
|
14029
|
+
`);
|
|
14030
|
+
}
|
|
13846
14031
|
async function main() {
|
|
13847
14032
|
if (flags.help || flags.h) {
|
|
13848
|
-
console.log(HELP);
|
|
14033
|
+
console.log(colorizeHelp(HELP));
|
|
13849
14034
|
process.exit(EXIT.SUCCESS);
|
|
13850
14035
|
}
|
|
13851
14036
|
if (flags.version || flags.V) {
|
|
@@ -14567,7 +14752,8 @@ async function main() {
|
|
|
14567
14752
|
const postFlags = {
|
|
14568
14753
|
mesh: flags.mesh,
|
|
14569
14754
|
json: !!flags.json,
|
|
14570
|
-
plaintext: !!flags.plaintext
|
|
14755
|
+
plaintext: !!flags.plaintext,
|
|
14756
|
+
replyTo: flags["reply-to"] || flags.replyTo
|
|
14571
14757
|
};
|
|
14572
14758
|
const message = positionals.slice(2).join(" ");
|
|
14573
14759
|
const { runTopicPost: runTopicPost2 } = await Promise.resolve().then(() => (init_topic_post(), exports_topic_post));
|
|
@@ -14660,4 +14846,4 @@ main().catch((err) => {
|
|
|
14660
14846
|
process.exit(EXIT.INTERNAL_ERROR);
|
|
14661
14847
|
});
|
|
14662
14848
|
|
|
14663
|
-
//# debugId=
|
|
14849
|
+
//# debugId=AEE2B186929FB60F64756E2164756E21
|