@indexnetwork/cli 0.10.6 → 0.10.7

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.
Files changed (3) hide show
  1. package/README.md +0 -1
  2. package/dist/index.js +127 -102
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -73,7 +73,6 @@ index intent update <id> "revised text" # Update a signal (runs full pipelin
73
73
  index intent archive <id> # Archive a signal
74
74
  index intent link <id> <network-id> # Link a signal to a network
75
75
  index intent unlink <id> <network-id> # Unlink a signal from a network
76
- index intent links <id> # List networks linked to a signal
77
76
  ```
78
77
 
79
78
  ### `index negotiation`
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ var __export = (target, all) => {
15
15
  };
16
16
 
17
17
  // src/main.ts
18
- import { execFile } from "node:child_process";
18
+ import { spawn } from "node:child_process";
19
19
 
20
20
  // src/args.parser.ts
21
21
  var KNOWN_COMMANDS = new Set(["login", "logout", "profile", "intent", "opportunity", "negotiation", "network", "conversation", "contact", "scrape", "onboarding", "sync", "help", "version"]);
@@ -217,7 +217,7 @@ function parseArgs(args) {
217
217
  }
218
218
  return result;
219
219
  }
220
- var INTENT_SUBCOMMANDS = new Set(["list", "show", "create", "archive", "update", "link", "unlink", "links"]);
220
+ var INTENT_SUBCOMMANDS = new Set(["list", "show", "create", "archive", "update", "link", "unlink"]);
221
221
  function parseIntentArgs(positionals, result) {
222
222
  if (positionals.length === 0)
223
223
  return;
@@ -229,7 +229,6 @@ function parseIntentArgs(positionals, result) {
229
229
  switch (result.subcommand) {
230
230
  case "show":
231
231
  case "archive":
232
- case "links":
233
232
  result.intentId = rest[0];
234
233
  break;
235
234
  case "create":
@@ -363,51 +362,60 @@ class ApiClient {
363
362
  const body = await res.json();
364
363
  return body.intent;
365
364
  }
365
+ async confirmIntent(proposalId, description, networkId) {
366
+ const res = await this.post("/api/intents/confirm", {
367
+ proposalId,
368
+ description,
369
+ ...networkId ? { networkId } : {}
370
+ });
371
+ const body = await res.json();
372
+ return body;
373
+ }
366
374
  async listNetworks() {
367
- const res = await this.get("/api/indexes");
375
+ const res = await this.get("/api/networks");
368
376
  const body = await res.json();
369
- return body.indexes.map((n) => ({
377
+ return body.networks.map((n) => ({
370
378
  ...n,
371
379
  joinPolicy: n.joinPolicy ?? n.permissions?.joinPolicy
372
380
  }));
373
381
  }
374
382
  async createNetwork(title, prompt) {
375
- const res = await this.post("/api/indexes", {
383
+ const res = await this.post("/api/networks", {
376
384
  title,
377
385
  ...prompt ? { prompt } : {}
378
386
  });
379
387
  const body = await res.json();
380
- return body.index;
388
+ return body.network;
381
389
  }
382
390
  async getNetwork(id) {
383
- const res = await this.get(`/api/indexes/${id}`);
391
+ const res = await this.get(`/api/networks/${id}`);
384
392
  const body = await res.json();
385
- const n = body.index;
393
+ const n = body.network;
386
394
  return { ...n, joinPolicy: n.joinPolicy ?? n.permissions?.joinPolicy };
387
395
  }
388
396
  async getNetworkMembers(id) {
389
- const res = await this.get(`/api/indexes/${id}/members`);
397
+ const res = await this.get(`/api/networks/${id}/members`);
390
398
  const body = await res.json();
391
399
  return body.members;
392
400
  }
393
401
  async joinNetwork(id) {
394
- const res = await this.post(`/api/indexes/${id}/join`, {});
402
+ const res = await this.post(`/api/networks/${id}/join`, {});
395
403
  const body = await res.json();
396
- return body.index;
404
+ return body.network;
397
405
  }
398
406
  async leaveNetwork(id) {
399
- await this.post(`/api/indexes/${id}/leave`, {});
407
+ await this.post(`/api/networks/${id}/leave`, {});
400
408
  }
401
409
  async searchUsers(query, networkId) {
402
410
  const params = new URLSearchParams({ q: query });
403
411
  if (networkId)
404
- params.set("indexId", networkId);
405
- const res = await this.get(`/api/indexes/search-users?${params.toString()}`);
412
+ params.set("networkId", networkId);
413
+ const res = await this.get(`/api/networks/search-users?${params.toString()}`);
406
414
  const body = await res.json();
407
415
  return body.users;
408
416
  }
409
417
  async addNetworkMember(networkId, userId) {
410
- const res = await this.post(`/api/indexes/${networkId}/members`, { userId });
418
+ const res = await this.post(`/api/networks/${networkId}/members`, { userId });
411
419
  const body = await res.json();
412
420
  return body;
413
421
  }
@@ -1056,10 +1064,10 @@ function profileCard(data) {
1056
1064
  const locLine = `Location: ${data.location}`;
1057
1065
  lines.push(` ${border("|")} ${GRAY}${locLine}${RESET}${padTo(W - 2, locLine)}${border("|")}`);
1058
1066
  }
1059
- if (data.socials && Object.keys(data.socials).length > 0) {
1067
+ if (data.socials && data.socials.length > 0) {
1060
1068
  lines.push(` ${border("|")}${" ".repeat(W)}${border("|")}`);
1061
- for (const [platform, url] of Object.entries(data.socials)) {
1062
- const socialLine = `${platform}: ${url}`;
1069
+ for (const { label, value } of data.socials) {
1070
+ const socialLine = `${label}: ${value}`;
1063
1071
  lines.push(` ${border("|")} ${BLUE}${socialLine}${RESET}${padTo(W - 2, socialLine)}${border("|")}`);
1064
1072
  }
1065
1073
  }
@@ -1233,51 +1241,41 @@ function opportunityTable(opportunities) {
1233
1241
  function opportunityCard(opp) {
1234
1242
  const width = 58;
1235
1243
  const innerWidth = width - 2;
1244
+ const title = opp.presentation?.title ?? "Opportunity";
1236
1245
  process.stdout.write(`
1237
1246
  ${BLUE}+${"─".repeat(width)}+${RESET}
1238
1247
  `);
1239
- process.stdout.write(` ${BLUE}|${RESET} ${BOLD}${BLUE}Opportunity${RESET}${" ".repeat(innerWidth - 12)}${BLUE}|${RESET}
1240
- `);
1248
+ cardLine(`${BOLD}${BLUE}${title}${RESET}`);
1241
1249
  process.stdout.write(` ${BLUE}+${"─".repeat(width)}+${RESET}
1242
1250
  `);
1243
1251
  const st = opp.status ?? "unknown";
1244
- const category = opp.interpretation?.category ?? "Uncategorized";
1245
1252
  cardLine(`${BOLD}Status:${RESET} ${statusColor(st)}${st}${RESET}`);
1246
- cardLine(`${BOLD}Category:${RESET} ${category}`);
1247
- if (opp.interpretation?.confidence != null) {
1248
- const bar = confidenceBar(opp.interpretation.confidence);
1249
- cardLine(`${BOLD}Confidence:${RESET} ${bar}`);
1250
- }
1251
- if (opp.actors && opp.actors.length > 0) {
1252
- process.stdout.write(` ${BLUE}|${RESET}${" ".repeat(innerWidth)}${BLUE}|${RESET}
1253
- `);
1254
- cardLine(`${BOLD}Parties:${RESET}`);
1255
- for (const actor of opp.actors) {
1256
- const name = actor.name ?? actor.userId;
1257
- const role = roleLabel(actor.role);
1258
- cardLine(` ${name} ${role}`);
1259
- }
1260
- }
1261
- if (opp.interpretation?.reasoning) {
1262
- process.stdout.write(` ${BLUE}|${RESET}${" ".repeat(innerWidth)}${BLUE}|${RESET}
1253
+ if (opp.category)
1254
+ cardLine(`${BOLD}Category:${RESET} ${opp.category}`);
1255
+ if (opp.index?.title)
1256
+ cardLine(`${BOLD}Network:${RESET} ${opp.index.title}`);
1257
+ if (opp.confidence != null)
1258
+ cardLine(`${BOLD}Confidence:${RESET} ${confidenceBar(opp.confidence)}`);
1259
+ if (opp.myRole)
1260
+ cardLine(`${BOLD}Your role:${RESET} ${roleLabel(opp.myRole)}`);
1261
+ if (opp.otherParties && opp.otherParties.length > 0) {
1262
+ process.stdout.write(` ${BLUE}|${RESET}
1263
1263
  `);
1264
- cardLine(`${BOLD}Reasoning:${RESET}`);
1265
- const wrapped = wordWrap(opp.interpretation.reasoning, innerWidth - 4);
1266
- for (const line of wrapped) {
1267
- cardLine(` ${AGENT_TEXT}${line}${RESET}`);
1264
+ cardLine(`${BOLD}With:${RESET}`);
1265
+ for (const p of opp.otherParties) {
1266
+ cardLine(` ${p.name ?? p.id} ${roleLabel(p.role)}`);
1268
1267
  }
1269
1268
  }
1270
- if (opp.presentation) {
1271
- process.stdout.write(` ${BLUE}|${RESET}${" ".repeat(innerWidth)}${BLUE}|${RESET}
1269
+ if (opp.presentation?.description) {
1270
+ process.stdout.write(` ${BLUE}|${RESET}
1272
1271
  `);
1273
- cardLine(`${BOLD}Presentation:${RESET}`);
1274
- const wrapped = wordWrap(opp.presentation, innerWidth - 4);
1275
- for (const line of wrapped) {
1272
+ cardLine(`${BOLD}Details:${RESET}`);
1273
+ for (const line of wordWrap(opp.presentation.description, innerWidth - 4)) {
1276
1274
  cardLine(` ${AGENT_TEXT}${line}${RESET}`);
1277
1275
  }
1278
1276
  }
1279
1277
  if (opp.createdAt) {
1280
- process.stdout.write(` ${BLUE}|${RESET}${" ".repeat(innerWidth)}${BLUE}|${RESET}
1278
+ process.stdout.write(` ${BLUE}|${RESET}
1281
1279
  `);
1282
1280
  const created = new Date(opp.createdAt).toLocaleString("en-US", {
1283
1281
  year: "numeric",
@@ -1367,8 +1365,8 @@ function memberTable(members) {
1367
1365
  console.log(` ${BOLD}${"Name".padEnd(nameW)} ${"Email".padEnd(emailW)} ${"Role".padEnd(roleW)} ${"Joined".padEnd(dateW)}${RESET}`);
1368
1366
  console.log(` ${GRAY}${"-".repeat(nameW)} ${"-".repeat(emailW)} ${"-".repeat(roleW)} ${"-".repeat(dateW)}${RESET}`);
1369
1367
  for (const m of members) {
1370
- const name = m.user.name.slice(0, nameW);
1371
- const email = m.user.email.slice(0, emailW);
1368
+ const name = (m.name ?? m.user?.name ?? "(unnamed)").slice(0, nameW);
1369
+ const email = (m.email ?? m.user?.email ?? "").slice(0, emailW);
1372
1370
  const role = m.permissions.includes("owner") ? "owner" : m.permissions.includes("admin") ? "admin" : "member";
1373
1371
  const date = m.createdAt ? new Date(m.createdAt).toLocaleDateString("en-US", {
1374
1372
  year: "numeric",
@@ -1390,7 +1388,7 @@ function conversationTable(conversations) {
1390
1388
  console.log(` ${GRAY}${"-".repeat(idWidth)} ${"-".repeat(participantsWidth)} ${"-".repeat(dateWidth)}${RESET}`);
1391
1389
  for (const c of conversations) {
1392
1390
  const shortId = c.id.slice(0, 8);
1393
- const names = c.participants.map((p) => p.user?.name ?? p.participantId).join(", ").slice(0, participantsWidth);
1391
+ const names = c.participants.map((p) => p.name ?? p.user?.name ?? p.participantId).join(", ").slice(0, participantsWidth);
1394
1392
  const date = new Date(c.createdAt).toLocaleDateString("en-US", {
1395
1393
  year: "numeric",
1396
1394
  month: "short",
@@ -1405,7 +1403,7 @@ function conversationCard(conversation) {
1405
1403
  console.log(` ${GRAY}${"─".repeat(40)}${RESET}`);
1406
1404
  console.log(` ${BOLD}ID${RESET} ${GRAY}${conversation.id}${RESET}`);
1407
1405
  if (conversation.participants.length > 0) {
1408
- const names = conversation.participants.map((p) => p.user?.name ?? p.participantId).join(", ");
1406
+ const names = conversation.participants.map((p) => p.name ?? p.user?.name ?? p.participantId).join(", ");
1409
1407
  console.log(` ${BOLD}Participants${RESET} ${names}`);
1410
1408
  }
1411
1409
  const date = new Date(conversation.createdAt).toLocaleDateString("en-US", {
@@ -1598,7 +1596,6 @@ Usage:
1598
1596
  index intent archive <id> Archive a signal (accepts short ID)
1599
1597
  index intent link <id> <network-id> Link a signal to a network
1600
1598
  index intent unlink <id> <network-id> Unlink a signal from a network
1601
- index intent links <id> Show linked networks for a signal
1602
1599
  `;
1603
1600
  async function handleIntent(client, subcommand, options) {
1604
1601
  if (!subcommand) {
@@ -1621,9 +1618,9 @@ async function handleIntent(client, subcommand, options) {
1621
1618
  }
1622
1619
  heading("Signals");
1623
1620
  intentTable(result.intents);
1624
- if (result.pagination.total > 0) {
1621
+ if (result.pagination.totalCount > 0) {
1625
1622
  dim(`
1626
- Page ${result.pagination.page} of ${result.pagination.totalPages} (${result.pagination.total} total)`);
1623
+ Page ${result.pagination.current} of ${result.pagination.total} (${result.pagination.totalCount} total)`);
1627
1624
  }
1628
1625
  console.log();
1629
1626
  return;
@@ -1659,10 +1656,16 @@ async function handleIntent(client, subcommand, options) {
1659
1656
  error(result.error ?? "Failed to create signal", 1);
1660
1657
  return;
1661
1658
  }
1662
- success("Signal created.");
1663
- const data = result.data;
1664
- if (data?.message)
1665
- dim(` ${data.message}`);
1659
+ const proposals = parseIntentProposals(result.data?.message);
1660
+ if (proposals.length === 0) {
1661
+ error("Signal proposal could not be parsed from the response.", 1);
1662
+ return;
1663
+ }
1664
+ for (const proposal of proposals) {
1665
+ await client.confirmIntent(proposal.proposalId, proposal.description);
1666
+ success("Signal created.");
1667
+ dim(` ${proposal.description}`);
1668
+ }
1666
1669
  return;
1667
1670
  }
1668
1671
  case "update": {
@@ -1714,8 +1717,9 @@ async function handleIntent(client, subcommand, options) {
1714
1717
  error("Usage: index intent link <intent-id> <network-id>", 1);
1715
1718
  return;
1716
1719
  }
1720
+ const intent = await client.getIntent(options.intentId);
1717
1721
  const result = await client.callTool("create_intent_index", {
1718
- intentId: options.intentId,
1722
+ intentId: intent.id,
1719
1723
  networkId: options.targetId
1720
1724
  });
1721
1725
  if (options.json) {
@@ -1734,8 +1738,9 @@ async function handleIntent(client, subcommand, options) {
1734
1738
  error("Usage: index intent unlink <intent-id> <network-id>", 1);
1735
1739
  return;
1736
1740
  }
1741
+ const intent = await client.getIntent(options.intentId);
1737
1742
  const result = await client.callTool("delete_intent_index", {
1738
- intentId: options.intentId,
1743
+ intentId: intent.id,
1739
1744
  networkId: options.targetId
1740
1745
  });
1741
1746
  if (options.json) {
@@ -1749,36 +1754,23 @@ async function handleIntent(client, subcommand, options) {
1749
1754
  success("Signal unlinked from network.");
1750
1755
  return;
1751
1756
  }
1752
- case "links": {
1753
- if (!options.intentId) {
1754
- error("Missing signal ID. Usage: index intent links <id>", 1);
1755
- return;
1756
- }
1757
- const result = await client.callTool("read_intent_indexes", {
1758
- intentId: options.intentId
1759
- });
1760
- if (options.json) {
1761
- console.log(JSON.stringify(result));
1762
- return;
1763
- }
1764
- if (!result.success) {
1765
- error(result.error ?? "Failed to read linked networks", 1);
1766
- return;
1767
- }
1768
- const data = result.data;
1769
- heading("Linked Networks");
1770
- if (!data.indexes?.length) {
1771
- dim(" No linked networks.");
1772
- } else {
1773
- for (const idx of data.indexes) {
1774
- const score = idx.relevancyScore !== undefined ? ` (${idx.relevancyScore.toFixed(2)})` : "";
1775
- console.log(` ${idx.title} ${DIM}${idx.networkId.slice(0, 8)}${score}${RESET}`);
1776
- }
1757
+ }
1758
+ }
1759
+ function parseIntentProposals(message) {
1760
+ if (!message)
1761
+ return [];
1762
+ const proposals = [];
1763
+ const blockRegex = /```intent_proposal\s*\n([\s\S]*?)\n```/g;
1764
+ let match;
1765
+ while ((match = blockRegex.exec(message)) !== null) {
1766
+ try {
1767
+ const parsed = JSON.parse(match[1]);
1768
+ if (parsed.proposalId && parsed.description) {
1769
+ proposals.push({ proposalId: parsed.proposalId, description: parsed.description });
1777
1770
  }
1778
- console.log();
1779
- return;
1780
- }
1771
+ } catch {}
1781
1772
  }
1773
+ return proposals;
1782
1774
  }
1783
1775
 
1784
1776
  // src/opportunity.command.ts
@@ -1859,9 +1851,7 @@ async function handleOpportunity(client, subcommand, options) {
1859
1851
  return;
1860
1852
  }
1861
1853
  success("Discovery complete.");
1862
- const data = result.data;
1863
- if (data?.message)
1864
- dim(` ${data.message}`);
1854
+ renderDiscovery(result.data);
1865
1855
  } else {
1866
1856
  if (!options.json)
1867
1857
  info("Discovering opportunities...");
@@ -1875,9 +1865,7 @@ async function handleOpportunity(client, subcommand, options) {
1875
1865
  return;
1876
1866
  }
1877
1867
  success("Discovery complete.");
1878
- const data = result.data;
1879
- if (data?.message)
1880
- dim(` ${data.message}`);
1868
+ renderDiscovery(result.data);
1881
1869
  }
1882
1870
  return;
1883
1871
  }
@@ -2003,9 +1991,44 @@ async function discoverIntroduction(client, userA, userB, hint, json) {
2003
1991
  return;
2004
1992
  }
2005
1993
  success("Introduction created.");
2006
- const data = result.data;
2007
- if (data?.message)
2008
- dim(` ${data.message}`);
1994
+ renderDiscovery(result.data);
1995
+ }
1996
+ function parseOpportunityCards(message) {
1997
+ const cards = [];
1998
+ const blockRegex = /```opportunity\s*\n([\s\S]*?)\n```/g;
1999
+ let match;
2000
+ while ((match = blockRegex.exec(message)) !== null) {
2001
+ try {
2002
+ const o = JSON.parse(match[1]);
2003
+ cards.push({
2004
+ name: typeof o.name === "string" ? o.name : undefined,
2005
+ headline: typeof o.headline === "string" ? o.headline : undefined,
2006
+ status: typeof o.status === "string" ? o.status : undefined
2007
+ });
2008
+ } catch {}
2009
+ }
2010
+ return cards;
2011
+ }
2012
+ function renderDiscovery(data) {
2013
+ const message = data?.message;
2014
+ if (!message) {
2015
+ dim(" No connections found.");
2016
+ return;
2017
+ }
2018
+ const cards = parseOpportunityCards(message);
2019
+ if (cards.length === 0) {
2020
+ const clean = message.replace(/IMPORTANT:[\s\S]*/i, "").trim();
2021
+ dim(` ${clean || "No connections found."}`);
2022
+ return;
2023
+ }
2024
+ dim(` Found ${cards.length} connection${cards.length === 1 ? "" : "s"}:`);
2025
+ for (const c of cards) {
2026
+ const tag = c.status && c.status !== "pending" ? ` ${DIM}[${c.status}]${RESET}` : "";
2027
+ console.log(` ${CYAN}*${RESET} ${c.name ?? "Unknown"}${tag}`);
2028
+ if (c.headline)
2029
+ dim(` ${c.headline}`);
2030
+ }
2031
+ dim("\n Review them with `index opportunity list`.");
2009
2032
  }
2010
2033
 
2011
2034
  // src/negotiation.command.ts
@@ -2885,7 +2908,7 @@ async function handleSync(client, options) {
2885
2908
  info("Syncing context...");
2886
2909
  const [profile, networks, intents, contacts] = await Promise.all([
2887
2910
  client.callTool("read_user_profiles", {}),
2888
- client.callTool("read_indexes", {}),
2911
+ client.callTool("read_networks", {}),
2889
2912
  client.callTool("read_intents", {}),
2890
2913
  client.callTool("list_contacts", {})
2891
2914
  ]);
@@ -2937,7 +2960,7 @@ async function onboardingComplete(client, json) {
2937
2960
  // src/main.ts
2938
2961
  var DEFAULT_API_URL = "https://protocol.index.network";
2939
2962
  var DEFAULT_APP_URL = "https://index.network";
2940
- var VERSION = "0.10.5";
2963
+ var VERSION = "0.10.6";
2941
2964
  var BOX = { tl: "╭", tr: "╮", bl: "╰", br: "╯", h: "─", v: "│" };
2942
2965
  function visualLen(s) {
2943
2966
  return stripAnsi(s).length;
@@ -3129,7 +3152,9 @@ async function runLogin(apiUrlOverride, appUrlOverride, manualToken) {
3129
3152
  try {
3130
3153
  const opener = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : null;
3131
3154
  if (opener) {
3132
- execFile(opener, [authUrl], { stdio: "ignore" });
3155
+ const child = spawn(opener, [authUrl], { stdio: "ignore", detached: true });
3156
+ child.on("error", () => {});
3157
+ child.unref();
3133
3158
  }
3134
3159
  } catch {}
3135
3160
  dim("Waiting for authentication callback...");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/cli",
3
- "version": "0.10.6",
3
+ "version": "0.10.7",
4
4
  "description": "Command-line interface for Index Network",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -20,10 +20,10 @@
20
20
  "publish:all": "bun scripts/publish.ts"
21
21
  },
22
22
  "optionalDependencies": {
23
- "@indexnetwork/cli-linux-x64": "0.10.6",
24
- "@indexnetwork/cli-linux-arm64": "0.10.6",
25
- "@indexnetwork/cli-darwin-x64": "0.10.6",
26
- "@indexnetwork/cli-darwin-arm64": "0.10.6"
23
+ "@indexnetwork/cli-linux-x64": "0.10.7",
24
+ "@indexnetwork/cli-linux-arm64": "0.10.7",
25
+ "@indexnetwork/cli-darwin-x64": "0.10.7",
26
+ "@indexnetwork/cli-darwin-arm64": "0.10.7"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/bun": "latest"