claudemesh-cli 1.0.0-alpha.40 → 1.0.0-alpha.42

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.
@@ -88,7 +88,7 @@ __export(exports_urls, {
88
88
  VERSION: () => VERSION,
89
89
  URLS: () => URLS
90
90
  });
91
- var URLS, VERSION = "1.0.0-alpha.40", env;
91
+ var URLS, VERSION = "1.0.0-alpha.42", env;
92
92
  var init_urls = __esm(() => {
93
93
  URLS = {
94
94
  BROKER: process.env.CLAUDEMESH_BROKER_URL ?? "wss://ic.claudemesh.com/ws",
@@ -4621,6 +4621,19 @@ async function runJoin(args) {
4621
4621
  console.error(" claudemesh join ic://join/eyJ2IjoxLC4uLn0 (v1 legacy)");
4622
4622
  process.exit(1);
4623
4623
  }
4624
+ if (!link.includes("://")) {
4625
+ const existing = readConfig().meshes.find((m) => m.slug === link || m.name === link);
4626
+ if (existing) {
4627
+ console.log(`Already in "${existing.slug}" on this machine.`);
4628
+ console.log("");
4629
+ console.log(`Use it in the current directory:`);
4630
+ console.log(` claudemesh launch --mesh ${existing.slug}`);
4631
+ console.log("");
4632
+ console.log(`Or list peers:`);
4633
+ console.log(` claudemesh peers --mesh ${existing.slug}`);
4634
+ return;
4635
+ }
4636
+ }
4624
4637
  const v2Code = parseV2InviteInput(link);
4625
4638
  if (v2Code) {
4626
4639
  await runJoinV2(v2Code);
@@ -6345,7 +6358,8 @@ async function runPeers(flags) {
6345
6358
  meta.push(p.model);
6346
6359
  const metaStr = meta.length ? dim(` (${meta.join(", ")})`) : "";
6347
6360
  const summary = p.summary ? dim(` — ${p.summary}`) : "";
6348
- render.info(`${statusDot} ${name}${groups}${metaStr}${summary}`);
6361
+ const pubkeyTag = dim(` · ${p.pubkey.slice(0, 16)}…`);
6362
+ render.info(`${statusDot} ${name}${groups}${metaStr}${pubkeyTag}${summary}`);
6349
6363
  if (p.cwd)
6350
6364
  render.info(dim(` cwd: ${p.cwd}`));
6351
6365
  }
@@ -9936,7 +9950,7 @@ async function resolveClient(to) {
9936
9950
  target = rest;
9937
9951
  }
9938
9952
  }
9939
- if (/^[0-9a-f]{64}$/.test(target) || target.startsWith("#") || target.startsWith("@") || target === "*") {
9953
+ if (target.startsWith("#") || target.startsWith("@") || target === "*") {
9940
9954
  if (targetClients.length === 1) {
9941
9955
  return { client: targetClients[0], targetSpec: target };
9942
9956
  }
@@ -9946,21 +9960,95 @@ async function resolveClient(to) {
9946
9960
  error: `multiple meshes joined; prefix target with "<mesh-slug>:" (joined: ${clients2.map((c) => c.meshSlug).join(", ")})`
9947
9961
  };
9948
9962
  }
9963
+ if (/^[0-9a-f]{8,64}$/.test(target)) {
9964
+ const hits = [];
9965
+ for (const c of targetClients) {
9966
+ const peers = await c.listPeers();
9967
+ for (const p of peers) {
9968
+ if (p.pubkey.startsWith(target)) {
9969
+ hits.push({ mesh: c, pubkey: p.pubkey, displayName: p.displayName });
9970
+ }
9971
+ }
9972
+ }
9973
+ if (hits.length === 1) {
9974
+ return { client: hits[0].mesh, targetSpec: hits[0].pubkey };
9975
+ }
9976
+ if (hits.length > 1) {
9977
+ const lines = hits.map((h) => ` - ${h.displayName} @ ${h.mesh.meshSlug} · pubkey ${h.pubkey.slice(0, 20)}…`).join(`
9978
+ `);
9979
+ return {
9980
+ client: null,
9981
+ targetSpec: target,
9982
+ error: `ambiguous pubkey prefix "${target}" matches ${hits.length} peers:
9983
+ ${lines}
9984
+ Use a longer prefix.`
9985
+ };
9986
+ }
9987
+ if (target.length === 64) {
9988
+ if (targetClients.length === 1) {
9989
+ return { client: targetClients[0], targetSpec: target };
9990
+ }
9991
+ return {
9992
+ client: null,
9993
+ targetSpec: target,
9994
+ error: `multiple meshes joined; prefix target with "<mesh-slug>:" (joined: ${clients2.map((c) => c.meshSlug).join(", ")})`
9995
+ };
9996
+ }
9997
+ return {
9998
+ client: null,
9999
+ targetSpec: target,
10000
+ error: `no online peer's pubkey starts with "${target}".`
10001
+ };
10002
+ }
9949
10003
  const nameLower = target.toLowerCase();
9950
10004
  const candidates = [];
10005
+ const exactMatches = [];
10006
+ const partialMatches = [];
9951
10007
  for (const c of targetClients) {
10008
+ const ownSession = c.getSessionPubkey();
9952
10009
  const peers = await c.listPeers();
9953
10010
  candidates.push({ mesh: c.meshSlug, peers });
9954
- const match = peers.find((p) => p.displayName.toLowerCase() === nameLower);
9955
- if (match)
9956
- return { client: c, targetSpec: match.pubkey };
9957
- const partials = peers.filter((p) => p.displayName.toLowerCase().includes(nameLower));
9958
- if (partials.length === 1) {
9959
- process.stderr.write(`[claudemesh] resolved "${target}" "${partials[0].displayName}" (partial match)
9960
- `);
9961
- return { client: c, targetSpec: partials[0].pubkey };
10011
+ for (const p of peers) {
10012
+ if (ownSession && p.pubkey === ownSession)
10013
+ continue;
10014
+ const nameLow = p.displayName.toLowerCase();
10015
+ if (nameLow === nameLower) {
10016
+ exactMatches.push({ mesh: c, pubkey: p.pubkey, displayName: p.displayName, cwd: p.cwd });
10017
+ } else if (nameLow.includes(nameLower)) {
10018
+ partialMatches.push({ mesh: c, pubkey: p.pubkey, displayName: p.displayName, cwd: p.cwd });
10019
+ }
9962
10020
  }
9963
10021
  }
10022
+ if (exactMatches.length === 1) {
10023
+ return { client: exactMatches[0].mesh, targetSpec: exactMatches[0].pubkey };
10024
+ }
10025
+ if (exactMatches.length > 1) {
10026
+ const lines = exactMatches.map((m) => ` - ${m.displayName} · pubkey ${m.pubkey.slice(0, 16)}…${m.cwd ? ` · cwd ${m.cwd}` : ""}`).join(`
10027
+ `);
10028
+ return {
10029
+ client: null,
10030
+ targetSpec: target,
10031
+ error: `"${target}" is ambiguous — ${exactMatches.length} peers share that display name:
10032
+ ${lines}
10033
+ ` + `Disambiguate by pubkey prefix (e.g. send to "${exactMatches[0].pubkey.slice(0, 12)}…").`
10034
+ };
10035
+ }
10036
+ if (partialMatches.length === 1) {
10037
+ process.stderr.write(`[claudemesh] resolved "${target}" → "${partialMatches[0].displayName}" (partial match)
10038
+ `);
10039
+ return { client: partialMatches[0].mesh, targetSpec: partialMatches[0].pubkey };
10040
+ }
10041
+ if (partialMatches.length > 1) {
10042
+ const lines = partialMatches.map((m) => ` - ${m.displayName} · pubkey ${m.pubkey.slice(0, 16)}…`).join(`
10043
+ `);
10044
+ return {
10045
+ client: null,
10046
+ targetSpec: target,
10047
+ error: `"${target}" partially matches ${partialMatches.length} peers:
10048
+ ${lines}
10049
+ Be more specific, or use a pubkey prefix.`
10050
+ };
10051
+ }
9964
10052
  const known = candidates.flatMap((c) => c.peers.map((p) => `${c.mesh}/${p.displayName}`));
9965
10053
  return {
9966
10054
  client: null,
@@ -10343,7 +10431,7 @@ No peers connected.`);
10343
10431
  const hiddenTag = p.visible === false ? " [hidden]" : "";
10344
10432
  const sameKeyCount = pubkeyCounts.get(p.pubkey) ?? 1;
10345
10433
  const sameKeyTag = sameKeyCount > 1 ? ` [shares key with ${sameKeyCount - 1} other session(s)]` : "";
10346
- return `- ${profileAvatar}**${p.displayName}**${profileTitle} [${p.status}]${localityTag}${hiddenTag}${sameKeyTag}${groupsStr}${metaStr} (${p.pubkey.slice(0, 12)}…)${cwdStr}${summary}`;
10434
+ return `- ${profileAvatar}**${p.displayName}**${profileTitle} [${p.status}]${localityTag}${hiddenTag}${sameKeyTag}${groupsStr}${metaStr} (pubkey: ${p.pubkey.slice(0, 16)}…)${cwdStr}${summary}`;
10347
10435
  });
10348
10436
  sections.push(`${header}
10349
10437
  ${peerLines.join(`
@@ -12675,4 +12763,4 @@ main().catch((err) => {
12675
12763
  process.exit(EXIT.INTERNAL_ERROR);
12676
12764
  });
12677
12765
 
12678
- //# debugId=BEBAC38EF8097F0D64756E2164756E21
12766
+ //# debugId=67051369A1B376A464756E2164756E21