@indexnetwork/cli 0.9.0 → 0.9.2

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 +5 -1
  2. package/dist/index.js +325 -120
  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
@@ -277,6 +280,7 @@ cli/
277
280
  contact.command.ts Contact subcommand handlers
278
281
  scrape.command.ts URL scraping command handler
279
282
  sync.command.ts Context sync command handler
283
+ onboarding.command.ts Onboarding command handler
280
284
  output/ Terminal formatting, colors, markdown renderer
281
285
  api.client.ts Typed HTTP client for the protocol API
282
286
  auth.store.ts Credential persistence (~/.index/credentials.json)
package/dist/index.js CHANGED
@@ -267,11 +267,6 @@ class ApiClient {
267
267
  const body = await res.json();
268
268
  return body.user;
269
269
  }
270
- async syncProfile() {
271
- const res = await this.post("/api/profiles/sync");
272
- const body = await res.json();
273
- return body;
274
- }
275
270
  async listOpportunities(opts) {
276
271
  const params = new URLSearchParams;
277
272
  if (opts?.status)
@@ -288,10 +283,6 @@ class ApiClient {
288
283
  const res = await this.get(`/api/opportunities/${id}`);
289
284
  return await res.json();
290
285
  }
291
- async updateOpportunityStatus(id, status) {
292
- const res = await this.patch(`/api/opportunities/${id}/status`, { status });
293
- return await res.json();
294
- }
295
286
  async streamChat(params) {
296
287
  const res = await fetch(`${this.baseUrl}/api/chat/stream`, {
297
288
  method: "POST",
@@ -327,14 +318,6 @@ class ApiClient {
327
318
  const body = await res.json();
328
319
  return body.intent;
329
320
  }
330
- async processIntent(content) {
331
- const res = await this.post("/api/intents/process", { content });
332
- return await res.json();
333
- }
334
- async archiveIntent(id) {
335
- const res = await this.patch(`/api/intents/${id}/archive`);
336
- return await res.json();
337
- }
338
321
  async listNetworks() {
339
322
  const res = await this.get("/api/indexes");
340
323
  const body = await res.json();
@@ -456,20 +439,6 @@ class ApiClient {
456
439
  }
457
440
  return res;
458
441
  }
459
- async patch(path, body) {
460
- const res = await fetch(`${this.baseUrl}${path}`, {
461
- method: "PATCH",
462
- headers: {
463
- "Content-Type": "application/json",
464
- Authorization: `Bearer ${this.token}`
465
- },
466
- ...body !== undefined ? { body: JSON.stringify(body) } : {}
467
- });
468
- if (!res.ok) {
469
- await this.handleError(res);
470
- }
471
- return res;
472
- }
473
442
  async del(path) {
474
443
  const res = await fetch(`${this.baseUrl}${path}`, {
475
444
  method: "DELETE",
@@ -1354,7 +1323,7 @@ function messageList(messages) {
1354
1323
  // src/profile.command.ts
1355
1324
  async function handleProfile(client, subcommand, positionals, options = {}) {
1356
1325
  if (subcommand === "create") {
1357
- await profileCreate(client, options);
1326
+ await profileCreate(client, options, options?.json);
1358
1327
  return;
1359
1328
  }
1360
1329
  if (subcommand === "update") {
@@ -1363,11 +1332,11 @@ async function handleProfile(client, subcommand, positionals, options = {}) {
1363
1332
  error("Usage: index profile update <action> [--details <text>]", 1);
1364
1333
  return;
1365
1334
  }
1366
- await profileUpdate(client, action, options.details);
1335
+ await profileUpdate(client, action, options.details, options?.json);
1367
1336
  return;
1368
1337
  }
1369
1338
  if (subcommand === "sync") {
1370
- await profileSync(client);
1339
+ await profileSync(client, options?.json);
1371
1340
  return;
1372
1341
  }
1373
1342
  if (subcommand === "show") {
@@ -1376,7 +1345,7 @@ async function handleProfile(client, subcommand, positionals, options = {}) {
1376
1345
  error("Usage: index profile show <user-id>", 1);
1377
1346
  return;
1378
1347
  }
1379
- await profileShow(client, userId);
1348
+ await profileShow(client, userId, options?.json);
1380
1349
  return;
1381
1350
  }
1382
1351
  if (subcommand === "search") {
@@ -1408,26 +1377,63 @@ async function handleProfile(client, subcommand, positionals, options = {}) {
1408
1377
  console.log();
1409
1378
  return;
1410
1379
  }
1411
- await profileMe(client);
1380
+ await profileMe(client, options?.json);
1412
1381
  }
1413
- async function profileMe(client) {
1414
- info("Loading your profile...");
1382
+ async function profileMe(client, json) {
1383
+ if (!json) {
1384
+ info("Loading your profile...");
1385
+ }
1415
1386
  const me = await client.getMe();
1416
1387
  const user = await client.getUser(me.id);
1388
+ if (json) {
1389
+ console.log(JSON.stringify(user));
1390
+ return;
1391
+ }
1417
1392
  profileCard(user);
1418
1393
  }
1419
- async function profileShow(client, userId) {
1420
- info("Loading profile...");
1394
+ async function profileShow(client, userId, json) {
1395
+ if (!json) {
1396
+ info("Loading profile...");
1397
+ }
1421
1398
  const user = await client.getUser(userId);
1399
+ if (json) {
1400
+ console.log(JSON.stringify(user));
1401
+ return;
1402
+ }
1422
1403
  profileCard(user);
1423
1404
  }
1424
- async function profileSync(client) {
1425
- info("Regenerating profile...");
1426
- await client.syncProfile();
1405
+ async function profileSync(client, json) {
1406
+ if (!json)
1407
+ info("Regenerating profile...");
1408
+ const check = await client.callTool("read_user_profiles", {});
1409
+ if (!check.success) {
1410
+ if (json) {
1411
+ console.log(JSON.stringify(check));
1412
+ return;
1413
+ }
1414
+ error(check.error ?? "Failed to check profile status", 1);
1415
+ return;
1416
+ }
1417
+ const hasProfile = check.data?.hasProfile;
1418
+ let result;
1419
+ if (hasProfile) {
1420
+ result = await client.callTool("update_user_profile", { action: "regenerate" });
1421
+ } else {
1422
+ result = await client.callTool("create_user_profile", { confirm: true });
1423
+ }
1424
+ if (json) {
1425
+ console.log(JSON.stringify(result));
1426
+ return;
1427
+ }
1428
+ if (!result.success) {
1429
+ error(result.error ?? "Profile regeneration failed", 1);
1430
+ return;
1431
+ }
1427
1432
  success("Profile regeneration triggered. It may take a moment to complete.");
1428
1433
  }
1429
- async function profileCreate(client, options) {
1430
- info("Creating profile...");
1434
+ async function profileCreate(client, options, json) {
1435
+ if (!json)
1436
+ info("Creating profile...");
1431
1437
  const query = { confirm: true };
1432
1438
  if (options.linkedin)
1433
1439
  query.linkedinUrl = options.linkedin;
@@ -1436,18 +1442,27 @@ async function profileCreate(client, options) {
1436
1442
  if (options.twitter)
1437
1443
  query.twitterUrl = options.twitter;
1438
1444
  const result = await client.callTool("create_user_profile", query);
1445
+ if (json) {
1446
+ console.log(JSON.stringify(result));
1447
+ return;
1448
+ }
1439
1449
  if (!result.success) {
1440
1450
  error(result.error ?? "Profile creation failed", 1);
1441
1451
  return;
1442
1452
  }
1443
1453
  success("Profile created.");
1444
1454
  }
1445
- async function profileUpdate(client, action, details) {
1446
- info("Updating profile...");
1455
+ async function profileUpdate(client, action, details, json) {
1456
+ if (!json)
1457
+ info("Updating profile...");
1447
1458
  const query = { action };
1448
1459
  if (details)
1449
1460
  query.details = details;
1450
1461
  const result = await client.callTool("update_user_profile", query);
1462
+ if (json) {
1463
+ console.log(JSON.stringify(result));
1464
+ return;
1465
+ }
1451
1466
  if (!result.success) {
1452
1467
  error(result.error ?? "Profile update failed", 1);
1453
1468
  return;
@@ -1513,16 +1528,23 @@ async function handleIntent(client, subcommand, options) {
1513
1528
  error("Missing content. Usage: index intent create <content>", 1);
1514
1529
  return;
1515
1530
  }
1516
- info("Processing signal...");
1517
- const result = await client.processIntent(options.intentContent);
1531
+ if (!options.json)
1532
+ info("Processing signal...");
1533
+ const result = await client.callTool("create_intent", {
1534
+ description: options.intentContent
1535
+ });
1518
1536
  if (options.json) {
1519
1537
  console.log(JSON.stringify(result));
1520
1538
  return;
1521
1539
  }
1522
- success("Signal processed successfully.");
1523
- if (result.message) {
1524
- dim(` ${result.message}`);
1540
+ if (!result.success) {
1541
+ error(result.error ?? "Failed to create signal", 1);
1542
+ return;
1525
1543
  }
1544
+ success("Signal created.");
1545
+ const data = result.data;
1546
+ if (data?.message)
1547
+ dim(` ${data.message}`);
1526
1548
  return;
1527
1549
  }
1528
1550
  case "update": {
@@ -1534,7 +1556,8 @@ async function handleIntent(client, subcommand, options) {
1534
1556
  error("Missing content. Usage: index intent update <id> <content>", 1);
1535
1557
  return;
1536
1558
  }
1537
- info("Updating signal...");
1559
+ if (!options.json)
1560
+ info("Updating signal...");
1538
1561
  const result = await client.callTool("update_intent", {
1539
1562
  intentId: options.intentId,
1540
1563
  newDescription: options.intentContent
@@ -1555,9 +1578,14 @@ async function handleIntent(client, subcommand, options) {
1555
1578
  error("Missing signal ID. Usage: index intent archive <id>", 1);
1556
1579
  return;
1557
1580
  }
1558
- await client.archiveIntent(options.intentId);
1581
+ const intent = await client.getIntent(options.intentId);
1582
+ const result = await client.callTool("delete_intent", { intentId: intent.id });
1559
1583
  if (options.json) {
1560
- console.log(JSON.stringify({ success: true }));
1584
+ console.log(JSON.stringify(result));
1585
+ return;
1586
+ }
1587
+ if (!result.success) {
1588
+ error(result.error ?? "Failed to archive signal", 1);
1561
1589
  return;
1562
1590
  }
1563
1591
  success(`Signal ${options.intentId} archived.`);
@@ -1688,32 +1716,51 @@ async function handleOpportunity(client, subcommand, options) {
1688
1716
  error("Usage: index opportunity discover <query>", 1);
1689
1717
  return;
1690
1718
  }
1691
- info("Discovering opportunities...");
1692
- const toolQuery = {};
1693
1719
  if (options.introduce) {
1694
- toolQuery.mode = "introduction";
1695
- toolQuery.sourceUserId = options.introduce;
1696
- toolQuery.targetUserId = options.positionals?.[0];
1720
+ const userA = options.introduce;
1721
+ const userB = options.positionals?.[0];
1722
+ if (!userB) {
1723
+ error("Usage: index opportunity discover --introduce <userA> <userB>", 1);
1724
+ return;
1725
+ }
1726
+ const hint = options.positionals?.slice(1).join(" ") || undefined;
1727
+ await discoverIntroduction(client, userA, userB, hint, options.json);
1697
1728
  } else if (options.target) {
1698
- toolQuery.mode = "direct";
1699
- toolQuery.targetUserId = options.target;
1700
- toolQuery.searchQuery = query;
1729
+ if (!options.json)
1730
+ info("Discovering opportunities...");
1731
+ const result = await client.callTool("create_opportunities", {
1732
+ targetUserId: options.target,
1733
+ searchQuery: query
1734
+ });
1735
+ if (options.json) {
1736
+ console.log(JSON.stringify(result));
1737
+ return;
1738
+ }
1739
+ if (!result.success) {
1740
+ error(result.error ?? "Discovery failed", 1);
1741
+ return;
1742
+ }
1743
+ success("Discovery complete.");
1744
+ const data = result.data;
1745
+ if (data?.message)
1746
+ dim(` ${data.message}`);
1701
1747
  } 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;
1748
+ if (!options.json)
1749
+ info("Discovering opportunities...");
1750
+ const result = await client.callTool("create_opportunities", { searchQuery: query });
1751
+ if (options.json) {
1752
+ console.log(JSON.stringify(result));
1753
+ return;
1754
+ }
1755
+ if (!result.success) {
1756
+ error(result.error ?? "Discovery failed", 1);
1757
+ return;
1758
+ }
1759
+ success("Discovery complete.");
1760
+ const data = result.data;
1761
+ if (data?.message)
1762
+ dim(` ${data.message}`);
1712
1763
  }
1713
- success("Discovery complete.");
1714
- const data = result.data;
1715
- if (data?.message)
1716
- dim(` ${data.message}`);
1717
1764
  return;
1718
1765
  }
1719
1766
  default:
@@ -1740,13 +1787,94 @@ async function opportunityShow(client, id, json) {
1740
1787
  opportunityCard(opportunity);
1741
1788
  }
1742
1789
  async function opportunityStatusUpdate(client, id, status2, json) {
1743
- const result = await client.updateOpportunityStatus(id, status2);
1790
+ const opportunity = await client.getOpportunity(id);
1791
+ const result = await client.callTool("update_opportunity", {
1792
+ opportunityId: opportunity.id,
1793
+ status: status2
1794
+ });
1744
1795
  if (json) {
1745
1796
  console.log(JSON.stringify(result));
1746
1797
  return;
1747
1798
  }
1748
- const label = status2 === "accepted" ? "accepted" : "rejected";
1749
- success(`Opportunity ${label}.`);
1799
+ if (!result.success) {
1800
+ error(result.error ?? `Failed to ${status2 === "accepted" ? "accept" : "reject"} opportunity`, 1);
1801
+ return;
1802
+ }
1803
+ success(`Opportunity ${status2 === "accepted" ? "accepted" : "rejected"}.`);
1804
+ }
1805
+ async function discoverIntroduction(client, userA, userB, hint, json) {
1806
+ info("Gathering data for introduction...");
1807
+ const [membershipsA, membershipsB] = await Promise.all([
1808
+ client.callTool("read_index_memberships", { userId: userA }),
1809
+ client.callTool("read_index_memberships", { userId: userB })
1810
+ ]);
1811
+ if (!membershipsA.success || !membershipsB.success) {
1812
+ const err = membershipsA.error ?? membershipsB.error ?? "Failed to read memberships";
1813
+ if (json) {
1814
+ console.log(JSON.stringify({ success: false, error: err }));
1815
+ return;
1816
+ }
1817
+ error(err, 1);
1818
+ return;
1819
+ }
1820
+ const indexesA = membershipsA.data?.memberships ?? membershipsA.data?.indexes ?? [];
1821
+ const indexesB = membershipsB.data?.memberships ?? membershipsB.data?.indexes ?? [];
1822
+ const idsA = new Set(indexesA.map((m) => m.indexId));
1823
+ const shared = indexesB.filter((m) => idsA.has(m.indexId));
1824
+ if (shared.length === 0) {
1825
+ const err = "No shared indexes found between these users. They must be members of at least one common network.";
1826
+ if (json) {
1827
+ console.log(JSON.stringify({ success: false, error: err }));
1828
+ return;
1829
+ }
1830
+ error(err, 1);
1831
+ return;
1832
+ }
1833
+ const sharedIndexId = shared[0].indexId;
1834
+ dim(` Found shared network: ${sharedIndexId}`);
1835
+ const [profileA, profileB, intentsA, intentsB] = await Promise.all([
1836
+ client.callTool("read_user_profiles", { userId: userA }),
1837
+ client.callTool("read_user_profiles", { userId: userB }),
1838
+ client.callTool("read_intents", { userId: userA, indexId: sharedIndexId }),
1839
+ client.callTool("read_intents", { userId: userB, indexId: sharedIndexId })
1840
+ ]);
1841
+ const extractProfile = (result2) => {
1842
+ if (!result2.success || !result2.data)
1843
+ return;
1844
+ const d = result2.data;
1845
+ if (d.profile)
1846
+ return d.profile;
1847
+ const profiles = d.profiles;
1848
+ return profiles?.[0]?.profile;
1849
+ };
1850
+ const extractIntents = (result2) => {
1851
+ if (!result2.success || !result2.data)
1852
+ return;
1853
+ const d = result2.data;
1854
+ return d.intents?.map((i) => ({ intentId: i.intentId ?? i.id ?? "", payload: i.payload, summary: i.summary }));
1855
+ };
1856
+ const entities = [
1857
+ { userId: userA, profile: extractProfile(profileA), intents: extractIntents(intentsA), indexId: sharedIndexId },
1858
+ { userId: userB, profile: extractProfile(profileB), intents: extractIntents(intentsB), indexId: sharedIndexId }
1859
+ ];
1860
+ dim(" Profiles and intents gathered. Creating introduction...");
1861
+ const result = await client.callTool("create_opportunities", {
1862
+ partyUserIds: [userA, userB],
1863
+ entities,
1864
+ ...hint ? { hint } : {}
1865
+ });
1866
+ if (json) {
1867
+ console.log(JSON.stringify(result));
1868
+ return;
1869
+ }
1870
+ if (!result.success) {
1871
+ error(result.error ?? "Introduction failed", 1);
1872
+ return;
1873
+ }
1874
+ success("Introduction created.");
1875
+ const data = result.data;
1876
+ if (data?.message)
1877
+ dim(` ${data.message}`);
1750
1878
  }
1751
1879
 
1752
1880
  // src/network.command.ts
@@ -1770,46 +1898,54 @@ async function handleNetwork(client, subcommand, positionals, options) {
1770
1898
  }
1771
1899
  switch (subcommand) {
1772
1900
  case "list":
1773
- await networkList(client);
1901
+ await networkList(client, options.json);
1774
1902
  return;
1775
1903
  case "create":
1776
- await networkCreate(client, positionals[0], options.prompt);
1904
+ await networkCreate(client, positionals[0], options.prompt, options.json);
1777
1905
  return;
1778
1906
  case "show":
1779
- await networkShow(client, positionals[0]);
1907
+ await networkShow(client, positionals[0], options.json);
1780
1908
  return;
1781
1909
  case "join":
1782
- await networkJoin(client, positionals[0]);
1910
+ await networkJoin(client, positionals[0], options.json);
1783
1911
  return;
1784
1912
  case "leave":
1785
- await networkLeave(client, positionals[0]);
1913
+ await networkLeave(client, positionals[0], options.json);
1786
1914
  return;
1787
1915
  case "update":
1788
- await networkUpdate(client, positionals[0], options);
1916
+ await networkUpdate(client, positionals[0], options, options.json);
1789
1917
  return;
1790
1918
  case "delete":
1791
- await networkDelete(client, positionals[0]);
1919
+ await networkDelete(client, positionals[0], options.json);
1792
1920
  return;
1793
1921
  case "invite":
1794
- await networkInvite(client, positionals[0], positionals[1]);
1922
+ await networkInvite(client, positionals[0], positionals[1], options.json);
1795
1923
  return;
1796
1924
  default:
1797
1925
  error(`Unknown network subcommand: ${subcommand}`, 1);
1798
1926
  }
1799
1927
  }
1800
- async function networkList(client) {
1928
+ async function networkList(client, json) {
1801
1929
  const networks = await client.listNetworks();
1802
1930
  const filtered = networks.filter((n) => !n.isPersonal);
1931
+ if (json) {
1932
+ console.log(JSON.stringify(filtered));
1933
+ return;
1934
+ }
1803
1935
  heading("Networks");
1804
1936
  networkTable(filtered);
1805
1937
  console.log();
1806
1938
  }
1807
- async function networkCreate(client, name, prompt) {
1939
+ async function networkCreate(client, name, prompt, json) {
1808
1940
  if (!name) {
1809
1941
  error("Usage: index network create <name>", 1);
1810
1942
  return;
1811
1943
  }
1812
1944
  const network = await client.createNetwork(name, prompt);
1945
+ if (json) {
1946
+ console.log(JSON.stringify(network));
1947
+ return;
1948
+ }
1813
1949
  success(`Network created: ${network.title}`);
1814
1950
  if (network.key) {
1815
1951
  dim(` Key: ${network.key}`);
@@ -1817,35 +1953,47 @@ async function networkCreate(client, name, prompt) {
1817
1953
  dim(` ID: ${network.id}`);
1818
1954
  dim(` Join Policy: ${(network.joinPolicy ?? "invite_only").replace("_", " ")}`);
1819
1955
  }
1820
- async function networkShow(client, id) {
1956
+ async function networkShow(client, id, json) {
1821
1957
  if (!id) {
1822
1958
  error("Usage: index network show <id>", 1);
1823
1959
  return;
1824
1960
  }
1825
1961
  const network = await client.getNetwork(id);
1826
- networkCard(network);
1827
1962
  const members = await client.getNetworkMembers(id);
1963
+ if (json) {
1964
+ console.log(JSON.stringify({ ...network, members }));
1965
+ return;
1966
+ }
1967
+ networkCard(network);
1828
1968
  heading("Members");
1829
1969
  memberTable(members);
1830
1970
  console.log();
1831
1971
  }
1832
- async function networkJoin(client, id) {
1972
+ async function networkJoin(client, id, json) {
1833
1973
  if (!id) {
1834
1974
  error("Usage: index network join <id>", 1);
1835
1975
  return;
1836
1976
  }
1837
1977
  const network = await client.joinNetwork(id);
1978
+ if (json) {
1979
+ console.log(JSON.stringify(network));
1980
+ return;
1981
+ }
1838
1982
  success(`Joined network: ${network.title}`);
1839
1983
  }
1840
- async function networkLeave(client, id) {
1984
+ async function networkLeave(client, id, json) {
1841
1985
  if (!id) {
1842
1986
  error("Usage: index network leave <id>", 1);
1843
1987
  return;
1844
1988
  }
1845
1989
  await client.leaveNetwork(id);
1990
+ if (json) {
1991
+ console.log(JSON.stringify({ id, left: true }));
1992
+ return;
1993
+ }
1846
1994
  success("Left network.");
1847
1995
  }
1848
- async function networkUpdate(client, id, options) {
1996
+ async function networkUpdate(client, id, options, json) {
1849
1997
  if (!id) {
1850
1998
  error("Usage: index network update <id> [--title <t>] [--prompt <p>]", 1);
1851
1999
  return;
@@ -1860,25 +2008,33 @@ async function networkUpdate(client, id, options) {
1860
2008
  return;
1861
2009
  }
1862
2010
  const result = await client.callTool("update_index", { indexId: id, settings });
2011
+ if (json) {
2012
+ console.log(JSON.stringify(result));
2013
+ return;
2014
+ }
1863
2015
  if (!result.success) {
1864
2016
  error(result.error ?? "Network update failed", 1);
1865
2017
  return;
1866
2018
  }
1867
2019
  success("Network updated.");
1868
2020
  }
1869
- async function networkDelete(client, id) {
2021
+ async function networkDelete(client, id, json) {
1870
2022
  if (!id) {
1871
2023
  error("Usage: index network delete <id>", 1);
1872
2024
  return;
1873
2025
  }
1874
2026
  const result = await client.callTool("delete_index", { indexId: id });
2027
+ if (json) {
2028
+ console.log(JSON.stringify(result));
2029
+ return;
2030
+ }
1875
2031
  if (!result.success) {
1876
2032
  error(result.error ?? "Network deletion failed", 1);
1877
2033
  return;
1878
2034
  }
1879
2035
  success("Network deleted.");
1880
2036
  }
1881
- async function networkInvite(client, id, email) {
2037
+ async function networkInvite(client, id, email, json) {
1882
2038
  if (!id || !email) {
1883
2039
  error("Usage: index network invite <id> <email>", 1);
1884
2040
  return;
@@ -1890,6 +2046,10 @@ async function networkInvite(client, id, email) {
1890
2046
  }
1891
2047
  const user = users[0];
1892
2048
  const result = await client.addNetworkMember(id, user.id);
2049
+ if (json) {
2050
+ console.log(JSON.stringify({ user, ...result }));
2051
+ return;
2052
+ }
1893
2053
  success(`Invited ${user.name} (${user.email}) to the network.`);
1894
2054
  if (result.message) {
1895
2055
  dim(` ${result.message}`);
@@ -2021,6 +2181,10 @@ Conversation Commands:
2021
2181
  `;
2022
2182
  async function handleConversation(client, subcommand, positionals, options) {
2023
2183
  if (!subcommand) {
2184
+ if (options?.json) {
2185
+ error("`--json` requires an explicit conversation subcommand.", 1);
2186
+ return;
2187
+ }
2024
2188
  if (options?.message) {
2025
2189
  await chatOneShot(client, options.message, options.sessionId);
2026
2190
  } else {
@@ -2030,19 +2194,19 @@ async function handleConversation(client, subcommand, positionals, options) {
2030
2194
  }
2031
2195
  switch (subcommand) {
2032
2196
  case "sessions":
2033
- await chatSessionsList(client);
2197
+ await chatSessionsList(client, options?.json);
2034
2198
  return;
2035
2199
  case "list":
2036
- await conversationList(client);
2200
+ await conversationList(client, options?.json);
2037
2201
  return;
2038
2202
  case "with":
2039
- await conversationWith(client, positionals[0]);
2203
+ await conversationWith(client, positionals[0], options?.json);
2040
2204
  return;
2041
2205
  case "show":
2042
- await conversationShow(client, positionals[0], options?.limit);
2206
+ await conversationShow(client, positionals[0], options?.limit, options?.json);
2043
2207
  return;
2044
2208
  case "send":
2045
- await conversationSend(client, positionals[0], positionals.slice(1));
2209
+ await conversationSend(client, positionals[0], positionals.slice(1), options?.json);
2046
2210
  return;
2047
2211
  case "stream":
2048
2212
  await conversationStream(client);
@@ -2054,30 +2218,42 @@ async function handleConversation(client, subcommand, positionals, options) {
2054
2218
  error(`Unknown conversation subcommand: ${subcommand}`, 1);
2055
2219
  }
2056
2220
  }
2057
- async function conversationList(client) {
2221
+ async function conversationList(client, json) {
2058
2222
  const conversations = await client.listConversations();
2223
+ if (json) {
2224
+ console.log(JSON.stringify(conversations));
2225
+ return;
2226
+ }
2059
2227
  heading("Conversations");
2060
2228
  conversationTable(conversations);
2061
2229
  console.log();
2062
2230
  }
2063
- async function conversationWith(client, userId) {
2231
+ async function conversationWith(client, userId, json) {
2064
2232
  if (!userId) {
2065
2233
  error("Usage: index conversation with <user-id>", 1);
2066
2234
  return;
2067
2235
  }
2068
2236
  const conversation = await client.getOrCreateDM(userId);
2237
+ if (json) {
2238
+ console.log(JSON.stringify(conversation));
2239
+ return;
2240
+ }
2069
2241
  conversationCard(conversation);
2070
2242
  }
2071
- async function conversationShow(client, id, limit) {
2243
+ async function conversationShow(client, id, limit, json) {
2072
2244
  if (!id) {
2073
2245
  error("Usage: index conversation show <id>", 1);
2074
2246
  return;
2075
2247
  }
2076
2248
  const messages = await client.getMessages(id, { limit: limit ?? 20 });
2249
+ if (json) {
2250
+ console.log(JSON.stringify(messages));
2251
+ return;
2252
+ }
2077
2253
  heading("Messages");
2078
2254
  messageList(messages);
2079
2255
  }
2080
- async function conversationSend(client, id, messageParts) {
2256
+ async function conversationSend(client, id, messageParts, json) {
2081
2257
  if (!id) {
2082
2258
  error("Usage: index conversation send <id> <message>", 1);
2083
2259
  return;
@@ -2088,6 +2264,10 @@ async function conversationSend(client, id, messageParts) {
2088
2264
  }
2089
2265
  const text = messageParts.join(" ");
2090
2266
  const msg = await client.sendMessage(id, text);
2267
+ if (json) {
2268
+ console.log(JSON.stringify(msg));
2269
+ return;
2270
+ }
2091
2271
  success(`Message sent (${msg.id})`);
2092
2272
  }
2093
2273
  async function conversationStream(client) {
@@ -2141,8 +2321,12 @@ async function conversationStream(client) {
2141
2321
  reader.releaseLock();
2142
2322
  }
2143
2323
  }
2144
- async function chatSessionsList(client) {
2324
+ async function chatSessionsList(client, json) {
2145
2325
  const sessions = await client.listSessions();
2326
+ if (json) {
2327
+ console.log(JSON.stringify(sessions));
2328
+ return;
2329
+ }
2146
2330
  heading("Chat Sessions");
2147
2331
  sessionTable(sessions);
2148
2332
  console.log();
@@ -2433,10 +2617,38 @@ async function handleSync(client, options) {
2433
2617
  success("Context synced to ~/.index/context.json");
2434
2618
  }
2435
2619
 
2620
+ // src/onboarding.command.ts
2621
+ var ONBOARDING_HELP = `
2622
+ Onboarding Commands:
2623
+ index onboarding complete Mark onboarding as complete
2624
+ `;
2625
+ async function handleOnboarding(client, subcommand, options) {
2626
+ if (subcommand === "complete") {
2627
+ await onboardingComplete(client, options?.json);
2628
+ return;
2629
+ }
2630
+ console.log(ONBOARDING_HELP);
2631
+ }
2632
+ async function onboardingComplete(client, json) {
2633
+ if (!json) {
2634
+ info("Completing onboarding...");
2635
+ }
2636
+ const result = await client.callTool("complete_onboarding", {});
2637
+ if (json) {
2638
+ console.log(JSON.stringify(result));
2639
+ return;
2640
+ }
2641
+ if (result.success) {
2642
+ success("Onboarding marked as complete.");
2643
+ } else {
2644
+ error(result.error ?? "Failed to complete onboarding.");
2645
+ }
2646
+ }
2647
+
2436
2648
  // src/main.ts
2437
2649
  var DEFAULT_API_URL = "https://protocol.index.network";
2438
2650
  var DEFAULT_APP_URL = "https://index.network";
2439
- var VERSION = "0.7.0";
2651
+ var VERSION = "0.9.2";
2440
2652
  var HELP_TEXT = `
2441
2653
  Index CLI v${VERSION}
2442
2654
 
@@ -2629,14 +2841,16 @@ async function main() {
2629
2841
  case "network":
2630
2842
  await handleNetwork(client, args.subcommand, args.positionals ?? [], {
2631
2843
  prompt: args.prompt,
2632
- title: args.title
2844
+ title: args.title,
2845
+ json: args.json
2633
2846
  });
2634
2847
  return;
2635
2848
  case "conversation":
2636
2849
  await handleConversation(client, args.subcommand, args.positionals ?? [], {
2637
2850
  limit: args.limit,
2638
2851
  sessionId: args.sessionId,
2639
- message: args.message
2852
+ message: args.message,
2853
+ json: args.json
2640
2854
  });
2641
2855
  return;
2642
2856
  case "contact":
@@ -2653,16 +2867,7 @@ async function main() {
2653
2867
  });
2654
2868
  return;
2655
2869
  case "onboarding":
2656
- if (args.subcommand === "complete") {
2657
- const result = await client.callTool("complete_onboarding", {});
2658
- if (!result.success) {
2659
- error(result.error ?? "Onboarding completion failed", 1);
2660
- } else {
2661
- success("Onboarding completed.");
2662
- }
2663
- } else {
2664
- error("Usage: index onboarding complete", 1);
2665
- }
2870
+ await handleOnboarding(client, args.subcommand, { json: args.json });
2666
2871
  return;
2667
2872
  case "sync":
2668
2873
  await handleSync(client, { json: args.json });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/cli",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
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.2",
24
+ "@indexnetwork/cli-linux-arm64": "0.9.2",
25
+ "@indexnetwork/cli-darwin-x64": "0.9.2",
26
+ "@indexnetwork/cli-darwin-arm64": "0.9.2"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/bun": "latest"