@indexnetwork/cli 0.9.0 → 0.9.1

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 +4 -1
  2. package/dist/index.js +113 -22
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -189,11 +189,14 @@ index opportunity discover "collaborate on open-source LLM tooling" --target <us
189
189
 
190
190
  ### Scenario 3: Introduction
191
191
 
192
- Introduce two people you think should connect. You become the introducer — both parties see you as the connector.
192
+ Introduce two people you think should connect. You become the introducer — both parties see you as the connector. The CLI automatically finds shared networks, gathers profiles and intents, then creates the introduction.
193
193
 
194
194
  ```bash
195
195
  # Introduce two users to each other
196
196
  index opportunity discover --introduce <user-id-a> <user-id-b>
197
+
198
+ # Provide a reason for the introduction
199
+ index opportunity discover --introduce <user-id-a> <user-id-b> "both working on privacy-preserving ML"
197
200
  ```
198
201
 
199
202
  ### Scenario 4: Review and act
package/dist/index.js CHANGED
@@ -1688,32 +1688,49 @@ async function handleOpportunity(client, subcommand, options) {
1688
1688
  error("Usage: index opportunity discover <query>", 1);
1689
1689
  return;
1690
1690
  }
1691
- info("Discovering opportunities...");
1692
- const toolQuery = {};
1693
1691
  if (options.introduce) {
1694
- toolQuery.mode = "introduction";
1695
- toolQuery.sourceUserId = options.introduce;
1696
- toolQuery.targetUserId = options.positionals?.[0];
1692
+ const userA = options.introduce;
1693
+ const userB = options.positionals?.[0];
1694
+ if (!userB) {
1695
+ error("Usage: index opportunity discover --introduce <userA> <userB>", 1);
1696
+ return;
1697
+ }
1698
+ const hint = options.positionals?.slice(1).join(" ") || undefined;
1699
+ await discoverIntroduction(client, userA, userB, hint, options.json);
1697
1700
  } else if (options.target) {
1698
- toolQuery.mode = "direct";
1699
- toolQuery.targetUserId = options.target;
1700
- toolQuery.searchQuery = query;
1701
+ info("Discovering opportunities...");
1702
+ const result = await client.callTool("create_opportunities", {
1703
+ targetUserId: options.target,
1704
+ searchQuery: query
1705
+ });
1706
+ if (options.json) {
1707
+ console.log(JSON.stringify(result));
1708
+ return;
1709
+ }
1710
+ if (!result.success) {
1711
+ error(result.error ?? "Discovery failed", 1);
1712
+ return;
1713
+ }
1714
+ success("Discovery complete.");
1715
+ const data = result.data;
1716
+ if (data?.message)
1717
+ dim(` ${data.message}`);
1701
1718
  } else {
1702
- toolQuery.searchQuery = query;
1703
- }
1704
- const result = await client.callTool("create_opportunities", toolQuery);
1705
- if (options.json) {
1706
- console.log(JSON.stringify(result));
1707
- return;
1708
- }
1709
- if (!result.success) {
1710
- error(result.error ?? "Discovery failed", 1);
1711
- return;
1719
+ info("Discovering opportunities...");
1720
+ const result = await client.callTool("create_opportunities", { searchQuery: query });
1721
+ if (options.json) {
1722
+ console.log(JSON.stringify(result));
1723
+ return;
1724
+ }
1725
+ if (!result.success) {
1726
+ error(result.error ?? "Discovery failed", 1);
1727
+ return;
1728
+ }
1729
+ success("Discovery complete.");
1730
+ const data = result.data;
1731
+ if (data?.message)
1732
+ dim(` ${data.message}`);
1712
1733
  }
1713
- success("Discovery complete.");
1714
- const data = result.data;
1715
- if (data?.message)
1716
- dim(` ${data.message}`);
1717
1734
  return;
1718
1735
  }
1719
1736
  default:
@@ -1748,6 +1765,80 @@ async function opportunityStatusUpdate(client, id, status2, json) {
1748
1765
  const label = status2 === "accepted" ? "accepted" : "rejected";
1749
1766
  success(`Opportunity ${label}.`);
1750
1767
  }
1768
+ async function discoverIntroduction(client, userA, userB, hint, json) {
1769
+ info("Gathering data for introduction...");
1770
+ const [membershipsA, membershipsB] = await Promise.all([
1771
+ client.callTool("read_index_memberships", { userId: userA }),
1772
+ client.callTool("read_index_memberships", { userId: userB })
1773
+ ]);
1774
+ if (!membershipsA.success || !membershipsB.success) {
1775
+ const err = membershipsA.error ?? membershipsB.error ?? "Failed to read memberships";
1776
+ if (json) {
1777
+ console.log(JSON.stringify({ success: false, error: err }));
1778
+ return;
1779
+ }
1780
+ error(err, 1);
1781
+ return;
1782
+ }
1783
+ const indexesA = membershipsA.data?.memberships ?? membershipsA.data?.indexes ?? [];
1784
+ const indexesB = membershipsB.data?.memberships ?? membershipsB.data?.indexes ?? [];
1785
+ const idsA = new Set(indexesA.map((m) => m.indexId));
1786
+ const shared = indexesB.filter((m) => idsA.has(m.indexId));
1787
+ if (shared.length === 0) {
1788
+ const err = "No shared indexes found between these users. They must be members of at least one common network.";
1789
+ if (json) {
1790
+ console.log(JSON.stringify({ success: false, error: err }));
1791
+ return;
1792
+ }
1793
+ error(err, 1);
1794
+ return;
1795
+ }
1796
+ const sharedIndexId = shared[0].indexId;
1797
+ dim(` Found shared network: ${sharedIndexId}`);
1798
+ const [profileA, profileB, intentsA, intentsB] = await Promise.all([
1799
+ client.callTool("read_user_profiles", { userId: userA }),
1800
+ client.callTool("read_user_profiles", { userId: userB }),
1801
+ client.callTool("read_intents", { userId: userA, indexId: sharedIndexId }),
1802
+ client.callTool("read_intents", { userId: userB, indexId: sharedIndexId })
1803
+ ]);
1804
+ const extractProfile = (result2) => {
1805
+ if (!result2.success || !result2.data)
1806
+ return;
1807
+ const d = result2.data;
1808
+ if (d.profile)
1809
+ return d.profile;
1810
+ const profiles = d.profiles;
1811
+ return profiles?.[0]?.profile;
1812
+ };
1813
+ const extractIntents = (result2) => {
1814
+ if (!result2.success || !result2.data)
1815
+ return;
1816
+ const d = result2.data;
1817
+ return d.intents?.map((i) => ({ intentId: i.intentId ?? i.id ?? "", payload: i.payload, summary: i.summary }));
1818
+ };
1819
+ const entities = [
1820
+ { userId: userA, profile: extractProfile(profileA), intents: extractIntents(intentsA), indexId: sharedIndexId },
1821
+ { userId: userB, profile: extractProfile(profileB), intents: extractIntents(intentsB), indexId: sharedIndexId }
1822
+ ];
1823
+ dim(" Profiles and intents gathered. Creating introduction...");
1824
+ const result = await client.callTool("create_opportunities", {
1825
+ partyUserIds: [userA, userB],
1826
+ entities,
1827
+ ...hint ? { hint } : {}
1828
+ });
1829
+ if (json) {
1830
+ console.log(JSON.stringify(result));
1831
+ return;
1832
+ }
1833
+ if (!result.success) {
1834
+ error(result.error ?? "Introduction failed", 1);
1835
+ return;
1836
+ }
1837
+ success("Introduction created.");
1838
+ const data = result.data;
1839
+ if (data?.message)
1840
+ dim(` ${data.message}`);
1841
+ }
1751
1842
 
1752
1843
  // src/network.command.ts
1753
1844
  var NETWORK_HELP = `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/cli",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
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.9.0",
24
- "@indexnetwork/cli-linux-arm64": "0.9.0",
25
- "@indexnetwork/cli-darwin-x64": "0.9.0",
26
- "@indexnetwork/cli-darwin-arm64": "0.9.0"
23
+ "@indexnetwork/cli-linux-x64": "0.9.1",
24
+ "@indexnetwork/cli-linux-arm64": "0.9.1",
25
+ "@indexnetwork/cli-darwin-x64": "0.9.1",
26
+ "@indexnetwork/cli-darwin-arm64": "0.9.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/bun": "latest"