@indexnetwork/cli 0.12.0-rc.53.1 → 0.13.0-rc.54.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 +8 -73
  2. package/dist/index.js +8 -190
  3. package/package.json +5 -5
package/README.md CHANGED
@@ -12,7 +12,7 @@ npm install -g @indexnetwork/cli
12
12
 
13
13
  Index helps you find the right people—and helps the right people find you—based on what you are actually trying to do, not just a profile headline. The value is grounded intros: suggestions come from communities you share (syndicates, founder groups, firm networks), not from spraying the open web.
14
14
 
15
- The flow below is one complete story—shape a room, invite people, publish what you need, run discovery inside that context, watch broker negotiations, then accept a match.
15
+ The flow below is one complete story—shape a room, invite people, publish an approved signal, let matching run in the background, then review a persisted match.
16
16
 
17
17
  ```bash
18
18
  # login + setup
@@ -22,14 +22,8 @@ index profile
22
22
  # 1. express intent (signals)
23
23
  index intent create "federated learning collaboration"
24
24
 
25
- # 2. discovery = sourcing + negotiations
26
- index opportunity discover "federated learning collaboration"
27
-
28
- # 3. check what the agents negotiated
29
- index negotiation list --since 1h
30
- index negotiation show <negotiation-id>
31
-
32
- # 4. review outcomes (opportunities) and decide
25
+ # 2. background matching evaluates approved signals
26
+ # Wait for persisted opportunities to be created, then review outcomes.
33
27
  index opportunity list --status pending
34
28
  index opportunity show <opportunity-id>
35
29
  index opportunity accept <opportunity-id>
@@ -102,9 +96,6 @@ index opportunity list --limit 5 # Limit results
102
96
  index opportunity show <id> # Show full details
103
97
  index opportunity accept <id> # Accept an opportunity
104
98
  index opportunity reject <id> # Reject an opportunity
105
- index opportunity discover "query" # Discover opportunities by search
106
- index opportunity discover --target <id> # Discover with a specific user
107
- index opportunity discover --introduce <a> <b> # Introduce two users
108
99
  ```
109
100
 
110
101
  Status values: `pending`, `accepted`, `rejected`, `expired`.
@@ -184,75 +175,21 @@ index sync # Sync to ~/.index/context.json
184
175
  index sync --json # Output to stdout as JSON
185
176
  ```
186
177
 
187
- ## Examples: Opportunity Discovery
188
-
189
- The `opportunity discover` command supports multiple modes for creating connections. Each mode can be combined with flags to customize the discovery.
190
-
191
- ### Search-based discovery
192
-
193
- Find people whose intents match a search query. The protocol runs HyDE-powered semantic search across your networks.
194
-
195
- ```bash
196
- index opportunity discover "looking for an AI engineer with privacy expertise"
197
- ```
198
-
199
- ### Targeted discovery
200
-
201
- Scope discovery to a specific user. Use when you already know who you want to connect with.
202
-
203
- ```bash
204
- # First, find the user
205
- index profile search "Jane Smith"
206
-
207
- # Then create a direct opportunity with them
208
- index opportunity discover "collaborate on open-source LLM tooling" --target <user-id>
209
- ```
178
+ ## Examples: Reviewing Opportunities
210
179
 
211
- ### Introduction
212
-
213
- 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.
214
-
215
- ```bash
216
- # Introduce two users to each other
217
- index opportunity discover --introduce <user-id-a> <user-id-b>
218
-
219
- # Provide a reason for the introduction
220
- index opportunity discover --introduce <user-id-a> <user-id-b> "both working on privacy-preserving ML"
221
- ```
222
-
223
- ### Complex social flows
224
-
225
- Use this when you want to propose an opportunity outright instead of running discovery: pick the community (`--network`), list each person (`--party`, two or more), and when it matters, tie a person to one of their signals with `userId:intentId` on that line and add why it fits (`--reason`). Here Alice and Bob carry explicit signals; Carol does not. This command is not in the CLI yet; it is the shape we intend to ship.
226
-
227
- ```bash
228
- index opportunity create \
229
- --network <network-id> \
230
- --party <alice-id>:<alice-intent-id> \
231
- --party <bob-id>:<bob-intent-id> \
232
- --party <carol-id> \
233
- --reason "Alice, Bob, and Carol are all working on federated learning from different angles" \
234
- --category "collaboration" \
235
- --confidence 0.9
236
- ```
180
+ Approved signals are matched in the background. `opportunity list` only reviews persisted results; it does not trigger matching.
237
181
 
238
182
  ### Review and act
239
183
 
240
- After discovery creates draft opportunities, review and accept/reject them.
241
-
242
184
  ```bash
243
- # List pending opportunities
185
+ # List persisted pending opportunities
244
186
  index opportunity list --status pending
245
187
 
246
- # See full details (reasoning, scores, mutual intents)
188
+ # See full details
247
189
  index opportunity show <id>
248
190
 
249
- # Accept — starts a conversation thread
191
+ # Accept or reject
250
192
  index opportunity accept <id>
251
-
252
- # If preparatory questions are returned, resolve them first or explicitly continue
253
- index opportunity accept <id> --acknowledge-uptake <question-id[,question-id...]>
254
-
255
- # Or reject
256
193
  index opportunity reject <id>
257
194
  ```
258
195
 
@@ -273,8 +210,6 @@ index opportunity reject <id>
273
210
  | `--title <text>` | | Network title (for `network update`) |
274
211
  | `--name <name>` | | Display name (for `contact add`) |
275
212
  | `--gmail` | | Import from Gmail (for `contact import`) |
276
- | `--target <id>` | | Target user ID (for `opportunity discover`) |
277
- | `--introduce <id>` | | Introduce two users (for `opportunity discover`) |
278
213
  | `--objective <text>` | | Focus objective (for `scrape`) |
279
214
  | `--json` | | Output raw JSON to stdout |
280
215
  | `--help` | `-h` | Show help |
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ 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"]);
22
- var OPPORTUNITY_SUBCOMMANDS = new Set(["list", "show", "accept", "reject", "discover"]);
22
+ var OPPORTUNITY_SUBCOMMANDS = new Set(["list", "show", "accept", "reject"]);
23
23
  var NEGOTIATION_SUBCOMMANDS = new Set(["list", "show"]);
24
24
  var NETWORK_SUBCOMMANDS = new Set(["list", "create", "show", "join", "leave", "invite", "update", "delete"]);
25
25
  var CONVERSATION_SUBCOMMANDS = new Set(["list", "with", "show", "send", "stream", "sessions", "help"]);
@@ -106,12 +106,6 @@ function parseArgs(args) {
106
106
  } else if (arg === "--objective") {
107
107
  result.objective = args[i + 1];
108
108
  i += 2;
109
- } else if (arg === "--target") {
110
- result.target = args[i + 1];
111
- i += 2;
112
- } else if (arg === "--introduce") {
113
- result.introduce = args[i + 1];
114
- i += 2;
115
109
  } else if (arg === "--linkedin") {
116
110
  result.linkedin = args[i + 1];
117
111
  i += 2;
@@ -144,11 +138,12 @@ function parseArgs(args) {
144
138
  const sub = positionals[0];
145
139
  if (sub && OPPORTUNITY_SUBCOMMANDS.has(sub)) {
146
140
  result.subcommand = sub;
147
- if (sub === "discover") {
148
- result.positionals = positionals.slice(1);
149
- } else if (positionals[1]) {
141
+ if (positionals[1]) {
150
142
  result.targetId = positionals[1];
151
143
  }
144
+ } else if (sub) {
145
+ result.command = "unknown";
146
+ result.unknown = `opportunity ${sub}`;
152
147
  }
153
148
  return result;
154
149
  }
@@ -1003,7 +998,6 @@ var TOOL_DESCRIPTIONS = {
1003
998
  delete_network: "Deleting community...",
1004
999
  create_network_membership: "Adding member to community...",
1005
1000
  read_network_memberships: "Fetching community memberships...",
1006
- discover_opportunities: "Searching for relevant connections...",
1007
1001
  list_opportunities: "Listing your opportunities...",
1008
1002
  update_opportunity: "Updating opportunity status...",
1009
1003
  scrape_url: "Reading content from URL...",
@@ -2007,9 +2001,6 @@ Usage:
2007
2001
  index opportunity accept <id> Accept an opportunity (accepts short ID)
2008
2002
  index opportunity accept <id> --acknowledge-uptake <id,id> Continue after an uptake advisory
2009
2003
  index opportunity reject <id> Reject an opportunity (accepts short ID)
2010
- index opportunity discover <query> Discover opportunities by search query
2011
- index opportunity discover --target <uid> <q> Discover for a specific user
2012
- index opportunity discover --introduce <a> <b> Introduce two users
2013
2004
  `;
2014
2005
  async function handleOpportunity(client, subcommand, options) {
2015
2006
  if (!subcommand) {
@@ -2045,41 +2036,6 @@ async function handleOpportunity(client, subcommand, options) {
2045
2036
  }
2046
2037
  await opportunityStatusUpdate(client, options.targetId, "rejected", options.json);
2047
2038
  return;
2048
- case "discover": {
2049
- const query = options.positionals?.join(" ");
2050
- if (!query && !options.introduce) {
2051
- error("Usage: index opportunity discover <query>", 1);
2052
- return;
2053
- }
2054
- if (options.introduce) {
2055
- const userA = options.introduce;
2056
- const userB = options.positionals?.[0];
2057
- if (!userB) {
2058
- error("Usage: index opportunity discover --introduce <userA> <userB>", 1);
2059
- return;
2060
- }
2061
- const hint = options.positionals?.slice(1).join(" ") || undefined;
2062
- await discoverIntroduction(client, userA, userB, hint, options.json);
2063
- return;
2064
- }
2065
- if (!options.json)
2066
- info("Discovering opportunities...");
2067
- const result = await client.callTool("discover_opportunities", {
2068
- ...options.target ? { targetUserId: options.target } : {},
2069
- searchQuery: query
2070
- });
2071
- if (options.json) {
2072
- console.log(JSON.stringify(result));
2073
- return;
2074
- }
2075
- if (!result.success) {
2076
- error(result.error ?? "Discovery failed", 1);
2077
- return;
2078
- }
2079
- success("Discovery complete.");
2080
- renderDiscovery(result.data);
2081
- return;
2082
- }
2083
2039
  default:
2084
2040
  error(`Unknown subcommand: ${subcommand}`, 1);
2085
2041
  return;
@@ -2157,135 +2113,6 @@ function uptakeAdvisoryFromError(error2) {
2157
2113
  const body = error2.response;
2158
2114
  return body?.advisory?.code === "unresolved_uptake_questions" ? body : null;
2159
2115
  }
2160
- async function discoverIntroduction(client, userA, userB, hint, json) {
2161
- if (!json)
2162
- info("Gathering data for introduction...");
2163
- const [membershipsA, membershipsB] = await Promise.all([
2164
- client.callTool("read_network_memberships", { userId: userA }),
2165
- client.callTool("read_network_memberships", { userId: userB })
2166
- ]);
2167
- if (!membershipsA.success || !membershipsB.success) {
2168
- const err = membershipsA.error ?? membershipsB.error ?? "Failed to read memberships";
2169
- if (json) {
2170
- console.log(JSON.stringify({ success: false, error: err }));
2171
- return;
2172
- }
2173
- error(err, 1);
2174
- return;
2175
- }
2176
- const indexesA = membershipsA.data?.memberships ?? membershipsA.data?.indexes ?? [];
2177
- const indexesB = membershipsB.data?.memberships ?? membershipsB.data?.indexes ?? [];
2178
- const idsA = new Set(indexesA.map((m) => m.networkId));
2179
- const shared = indexesB.filter((m) => idsA.has(m.networkId));
2180
- if (shared.length === 0) {
2181
- const err = "No shared networks found between these users. They must be members of at least one common network.";
2182
- if (json) {
2183
- console.log(JSON.stringify({ success: false, error: err }));
2184
- return;
2185
- }
2186
- error(err, 1);
2187
- return;
2188
- }
2189
- const sharedNetworkId = shared[0].networkId;
2190
- if (!json)
2191
- dim(` Found shared network: ${sharedNetworkId}`);
2192
- const [profileA, profileB, intentsA, intentsB] = await Promise.all([
2193
- client.callTool("read_user_profiles", { userId: userA }),
2194
- client.callTool("read_user_profiles", { userId: userB }),
2195
- client.callTool("read_intents", { userId: userA, networkId: sharedNetworkId }),
2196
- client.callTool("read_intents", { userId: userB, networkId: sharedNetworkId })
2197
- ]);
2198
- const gatherError = profileA.error ?? profileB.error ?? intentsA.error ?? intentsB.error;
2199
- if (!profileA.success || !profileB.success || !intentsA.success || !intentsB.success) {
2200
- const err = gatherError ?? "Failed to gather profiles and intents for introduction.";
2201
- if (json) {
2202
- console.log(JSON.stringify({ success: false, error: err }));
2203
- return;
2204
- }
2205
- error(err, 1);
2206
- return;
2207
- }
2208
- const extractProfile = (result2) => {
2209
- if (!result2.success || !result2.data)
2210
- return;
2211
- const d = result2.data;
2212
- if (d.profile)
2213
- return d.profile;
2214
- const profiles = d.profiles;
2215
- if (profiles?.length) {
2216
- const first = profiles[0];
2217
- return first.profile ?? first;
2218
- }
2219
- if (typeof d.name === "string" || typeof d.context === "string") {
2220
- return { name: d.name, bio: d.bio, location: d.location, context: d.context };
2221
- }
2222
- return;
2223
- };
2224
- const extractIntents = (result2) => {
2225
- if (!result2.success || !result2.data)
2226
- return;
2227
- const d = result2.data;
2228
- return d.intents?.map((i) => ({ intentId: i.intentId ?? i.id ?? "", payload: i.payload, summary: i.summary }));
2229
- };
2230
- const entities = [
2231
- { userId: userA, profile: extractProfile(profileA), intents: extractIntents(intentsA), networkId: sharedNetworkId },
2232
- { userId: userB, profile: extractProfile(profileB), intents: extractIntents(intentsB), networkId: sharedNetworkId }
2233
- ];
2234
- if (!json)
2235
- dim(" Profiles and intents gathered. Creating introduction...");
2236
- const result = await client.callTool("discover_opportunities", {
2237
- partyUserIds: [userA, userB],
2238
- entities,
2239
- ...hint ? { hint } : {}
2240
- });
2241
- if (json) {
2242
- console.log(JSON.stringify(result));
2243
- return;
2244
- }
2245
- if (!result.success) {
2246
- error(result.error ?? "Introduction failed", 1);
2247
- return;
2248
- }
2249
- success("Introduction created.");
2250
- renderDiscovery(result.data);
2251
- }
2252
- function parseOpportunityCards(message) {
2253
- const cards = [];
2254
- const blockRegex = /```opportunity\s*\n([\s\S]*?)\n```/g;
2255
- let match;
2256
- while ((match = blockRegex.exec(message)) !== null) {
2257
- try {
2258
- const o = JSON.parse(match[1]);
2259
- cards.push({
2260
- name: typeof o.name === "string" ? o.name : undefined,
2261
- headline: typeof o.headline === "string" ? o.headline : undefined,
2262
- status: typeof o.status === "string" ? o.status : undefined
2263
- });
2264
- } catch {}
2265
- }
2266
- return cards;
2267
- }
2268
- function renderDiscovery(data) {
2269
- const message = data?.message;
2270
- if (!message) {
2271
- dim(" No connections found.");
2272
- return;
2273
- }
2274
- const cards = parseOpportunityCards(message);
2275
- if (cards.length === 0) {
2276
- const clean = message.replace(/IMPORTANT:[\s\S]*/i, "").trim();
2277
- dim(` ${clean || "No connections found."}`);
2278
- return;
2279
- }
2280
- dim(` Found ${cards.length} connection${cards.length === 1 ? "" : "s"}:`);
2281
- for (const c of cards) {
2282
- const tag = c.status && c.status !== "pending" ? ` ${DIM}[${c.status}]${RESET}` : "";
2283
- console.log(` ${CYAN}*${RESET} ${c.name ?? "Unknown"}${tag}`);
2284
- if (c.headline)
2285
- dim(` ${c.headline}`);
2286
- }
2287
- dim("\n Review them with `index opportunity list`.");
2288
- }
2289
2116
 
2290
2117
  // src/negotiation.command.ts
2291
2118
  var NEGOTIATION_HELP = `
@@ -3226,7 +3053,7 @@ async function onboardingComplete(client, json) {
3226
3053
  // src/main.ts
3227
3054
  var DEFAULT_API_URL = "https://protocol.index.network";
3228
3055
  var DEFAULT_APP_URL = "https://index.network";
3229
- var VERSION = "0.12.0";
3056
+ var VERSION = "0.13.0";
3230
3057
  var BOX = { tl: "╭", tr: "╮", bl: "╰", br: "╯", h: "─", v: "│" };
3231
3058
  function visualLen(s) {
3232
3059
  return stripAnsi(s).length;
@@ -3274,8 +3101,7 @@ function renderHelp() {
3274
3101
  "index profile update",
3275
3102
  "index intent list",
3276
3103
  "index negotiation list",
3277
- "index opportunity list",
3278
- "index opportunity discover"
3104
+ "index opportunity list"
3279
3105
  ];
3280
3106
  const formsLW = Math.max(...formsLefts.map((s) => s.length));
3281
3107
  const cmdLefts = [
@@ -3306,8 +3132,6 @@ function renderHelp() {
3306
3132
  "--name <name>",
3307
3133
  "--gmail",
3308
3134
  "--objective <text>",
3309
- "--target <uid>",
3310
- "--introduce <uid>",
3311
3135
  "--linkedin <url>",
3312
3136
  "--github <url>",
3313
3137
  "--twitter <url>",
@@ -3338,8 +3162,7 @@ function renderHelp() {
3338
3162
  helpRowCmd(formsLW, "index profile update", "use action text or --details"),
3339
3163
  helpRowCmd(formsLW, "index intent list", "supports --archived and --limit"),
3340
3164
  helpRowCmd(formsLW, "index negotiation list", "supports --since and --limit"),
3341
- helpRowCmd(formsLW, "index opportunity list", "supports --status and --limit"),
3342
- helpRowCmd(formsLW, "index opportunity discover", "supports --target and --introduce")
3165
+ helpRowCmd(formsLW, "index opportunity list", "supports --status and --limit")
3343
3166
  ]);
3344
3167
  panel("commands", [
3345
3168
  helpRowDim(cmdLW, "pattern", "index <command> [args] [options]"),
@@ -3348,7 +3171,6 @@ function renderHelp() {
3348
3171
  helpRowCmd(cmdLW, "intent", "list · show · create · update · archive"),
3349
3172
  helpRowCont(cmdLW, "link · unlink · links"),
3350
3173
  helpRowCmd(cmdLW, "negotiation", "list · show"),
3351
- helpRowCmd(cmdLW, "opportunity", "list · show · accept · reject · discover"),
3352
3174
  "",
3353
3175
  helpRowCmd(cmdLW, "profile", "show · sync · search · create · update"),
3354
3176
  helpRowCmd(cmdLW, "conversation", "sessions · list · with · show · send · stream"),
@@ -3373,8 +3195,6 @@ function renderHelp() {
3373
3195
  helpRowDim(optLW, "--name <name>", "name for contact add"),
3374
3196
  helpRowDim(optLW, "--gmail", "import contacts from Gmail"),
3375
3197
  helpRowDim(optLW, "--objective <text>", "objective for scrape command"),
3376
- helpRowDim(optLW, "--target <uid>", "target user for opportunity discovery"),
3377
- helpRowDim(optLW, "--introduce <uid>", "source user for introduction discovery"),
3378
3198
  helpRowDim(optLW, "--linkedin <url>", "LinkedIn URL for profile create"),
3379
3199
  helpRowDim(optLW, "--github <url>", "GitHub URL for profile create"),
3380
3200
  helpRowDim(optLW, "--twitter <url>", "Twitter URL for profile create"),
@@ -3530,8 +3350,6 @@ async function main() {
3530
3350
  limit: args.limit,
3531
3351
  json: args.json,
3532
3352
  positionals: args.positionals,
3533
- target: args.target,
3534
- introduce: args.introduce,
3535
3353
  acknowledgeUptake: args.acknowledgeUptake
3536
3354
  });
3537
3355
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indexnetwork/cli",
3
- "version": "0.12.0-rc.53.1",
3
+ "version": "0.13.0-rc.54.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.12.0-rc.53.1",
24
- "@indexnetwork/cli-linux-arm64": "0.12.0-rc.53.1",
25
- "@indexnetwork/cli-darwin-x64": "0.12.0-rc.53.1",
26
- "@indexnetwork/cli-darwin-arm64": "0.12.0-rc.53.1"
23
+ "@indexnetwork/cli-linux-x64": "0.13.0-rc.54.1",
24
+ "@indexnetwork/cli-linux-arm64": "0.13.0-rc.54.1",
25
+ "@indexnetwork/cli-darwin-x64": "0.13.0-rc.54.1",
26
+ "@indexnetwork/cli-darwin-arm64": "0.13.0-rc.54.1"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/bun": "latest"