@indexnetwork/cli 0.28.0 → 0.29.0-rc.88.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.
- package/README.md +35 -35
- package/dist/index.js +336 -59
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Index CLI
|
|
2
2
|
|
|
3
|
-
Command-line interface for [Index Network](https://index.network). Message your personal agent, manage
|
|
3
|
+
Command-line interface for [Index Network](https://index.network). Message your personal agent, manage intents, and discover opportunities — all from your terminal.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -12,17 +12,17 @@ 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—
|
|
15
|
+
The flow below is one complete story—create an intent, let agents negotiate in the background, then review a persisted match.
|
|
16
16
|
|
|
17
17
|
```bash
|
|
18
18
|
# login + setup
|
|
19
19
|
index login
|
|
20
20
|
index profile
|
|
21
21
|
|
|
22
|
-
# 1. express intent
|
|
22
|
+
# 1. express an intent
|
|
23
23
|
index intent create "federated learning collaboration"
|
|
24
24
|
|
|
25
|
-
# 2.
|
|
25
|
+
# 2. agents negotiate on your intents in the background
|
|
26
26
|
index negotiation list
|
|
27
27
|
|
|
28
28
|
# 3. wait for persisted opportunities, then review outcomes
|
|
@@ -53,16 +53,16 @@ flags are listed in [Options](#options), and examples follow this reference.
|
|
|
53
53
|
| `index profile show <user-id>` | Show another user's accessible profile. |
|
|
54
54
|
| `index profile sync` | Research public profile information and return a suggested profile without persisting it. |
|
|
55
55
|
| `index profile update` | Save reviewed name, bio, location, or social links. |
|
|
56
|
-
| `index intent list` | List
|
|
57
|
-
| `index intent show <id>` | Show one
|
|
56
|
+
| `index intent list` | List intents, with optional archived, text-query, and result-limit filters. |
|
|
57
|
+
| `index intent show <id>` | Show one intent. |
|
|
58
58
|
| `index intent prepare <text>` | Prepare a draft, optionally answering recovery prompts; returns an admission receipt when ready. |
|
|
59
|
-
| `index intent create <text>` | Create
|
|
60
|
-
| `index intent update <id> <text>` | Update and reprocess
|
|
61
|
-
| `index intent archive <id>` | Archive
|
|
59
|
+
| `index intent create <text>` | Create an intent, optionally using the preparation receipt. |
|
|
60
|
+
| `index intent update <id> <text>` | Update and reprocess an intent's description. |
|
|
61
|
+
| `index intent archive <id>` | Archive an intent so it stops participating in discovery. |
|
|
62
62
|
| `index intent pause <id>` / `resume <id>` | Pause or resume its agent without archiving. |
|
|
63
|
-
| `index intent networks <id>` | List the networks
|
|
64
|
-
| `index intent add-to-network <id> <network-id>` | Share
|
|
65
|
-
| `index intent remove-from-network <id> <network-id>` | Stop sharing
|
|
63
|
+
| `index intent networks <id>` | List the networks an intent is shared in. |
|
|
64
|
+
| `index intent add-to-network <id> <network-id>` | Share an intent in a network. |
|
|
65
|
+
| `index intent remove-from-network <id> <network-id>` | Stop sharing an intent in a network. |
|
|
66
66
|
| `index negotiation list` | List negotiations, optionally filtered by intent or open/settled state. |
|
|
67
67
|
| `index negotiation show <opportunity-id>` | Read the negotiation's turns, current state, and available actions. |
|
|
68
68
|
| `index negotiation turn <opportunity-id> --action <action> --message <text> --expected-turn-count <n>` | Submit one `propose`, `counter`, `accept`, or `decline` turn against the observed turn count. |
|
|
@@ -76,7 +76,7 @@ flags are listed in [Options](#options), and examples follow this reference.
|
|
|
76
76
|
| `index network requests` / `request-update` / `request-dismiss` | Review or revise your early-access creation requests. |
|
|
77
77
|
| `index network create <title>` | Create a network when eligible, or submit an early-access creation request. |
|
|
78
78
|
| `index network show <id>` | Show a network and its members. |
|
|
79
|
-
| `index network update <id> --title <text
|
|
79
|
+
| `index network update <id> [--title <text>] [--prompt <text>]` | Change a network's title or description. |
|
|
80
80
|
| `index network delete <id>` | Delete a network you own. |
|
|
81
81
|
| `index network join <id>` | Join an open network. |
|
|
82
82
|
| `index network leave <id>` | Leave a network. |
|
|
@@ -89,9 +89,9 @@ flags are listed in [Options](#options), and examples follow this reference.
|
|
|
89
89
|
| `index conversation stream` | Subscribe to conversation, negotiation, opportunity, and intent events over SSE. |
|
|
90
90
|
| `index conversation help` | Show conversation-specific help. |
|
|
91
91
|
| `index onboarding confirm-profile` | Confirm that the owner has reviewed their profile. |
|
|
92
|
-
| `index onboarding complete` | Complete onboarding once profile confirmation and first-
|
|
92
|
+
| `index onboarding complete` | Complete onboarding once profile confirmation and first-intent prerequisites are met. |
|
|
93
93
|
| `index scrape <url>` | Extract text from a URL, optionally guided by an objective. |
|
|
94
|
-
| `index sync` | Read your profile, networks, and
|
|
94
|
+
| `index sync` | Read your profile, networks, and intents into `~/.index/context.json`, or stdout with `--json`. |
|
|
95
95
|
|
|
96
96
|
### `index login`
|
|
97
97
|
|
|
@@ -142,31 +142,31 @@ index logout
|
|
|
142
142
|
|
|
143
143
|
### `index intent`
|
|
144
144
|
|
|
145
|
-
Manage your
|
|
145
|
+
Manage your intents. Create intents from natural language, list active intents, view details, and archive intents you no longer need.
|
|
146
146
|
|
|
147
147
|
```bash
|
|
148
|
-
index intent list # List active
|
|
149
|
-
index intent list --archived # Include archived
|
|
148
|
+
index intent list # List active intents
|
|
149
|
+
index intent list --archived # Include archived intents
|
|
150
150
|
index intent list --limit 5 # Limit to 5 results
|
|
151
151
|
index intent list --query "CTO" # Match description and summary text
|
|
152
|
-
index intent show <id> # Show full
|
|
152
|
+
index intent show <id> # Show full intent details
|
|
153
153
|
index intent prepare "Looking for a CTO" # Read feedback / recovery prompts and receipt
|
|
154
154
|
index intent prepare "Looking for a CTO" --answer 'Prompt label=My answer'
|
|
155
155
|
index intent create "<returned payload>" --receipt '<returned preparationReceipt>'
|
|
156
156
|
index intent pause <id> # Hold the agent without archiving
|
|
157
157
|
index intent resume <id> # Start it again
|
|
158
|
-
index intent update <id> "revised text" # Update
|
|
159
|
-
index intent archive <id> # Archive
|
|
160
|
-
index intent networks <id> # List the networks
|
|
161
|
-
index intent add-to-network <id> <network-id> # Add
|
|
162
|
-
index intent remove-from-network <id> <network-id> # Remove
|
|
158
|
+
index intent update <id> "revised text" # Update an intent (runs full pipeline)
|
|
159
|
+
index intent archive <id> # Archive an intent
|
|
160
|
+
index intent networks <id> # List the networks an intent is shared in
|
|
161
|
+
index intent add-to-network <id> <network-id> # Add an intent to a network
|
|
162
|
+
index intent remove-from-network <id> <network-id> # Remove an intent from a network
|
|
163
163
|
```
|
|
164
164
|
|
|
165
165
|
Preparation returns `needs_revision` with recovery field labels or `ready` with a
|
|
166
166
|
`payload` and `preparationReceipt`. Use the exact returned payload with its receipt
|
|
167
167
|
in `create`; `--answer` pairs the displayed recovery **label** with your response.
|
|
168
168
|
You can also create directly: the server prepares the description and rejects an
|
|
169
|
-
unadmitted draft. A new
|
|
169
|
+
unadmitted draft. A new intent is shared in every network you belong to. Narrow it afterwards with
|
|
170
170
|
`remove-from-network`, or widen an existing one with `add-to-network`.
|
|
171
171
|
|
|
172
172
|
### `index negotiation`
|
|
@@ -203,7 +203,7 @@ index opportunity start-chat <id> # Open its human chat (pending/accept
|
|
|
203
203
|
|
|
204
204
|
`--status` accepts one of `pending`, `accepted`, `rejected`, `expired`;
|
|
205
205
|
`--statuses` accepts a comma-separated radar selection including `negotiating`.
|
|
206
|
-
The
|
|
206
|
+
The intent-scoped radar uses `--intent-id <id>`.
|
|
207
207
|
|
|
208
208
|
### `index network`
|
|
209
209
|
|
|
@@ -227,7 +227,7 @@ index network invite <id> user@email # Invite directly by email
|
|
|
227
227
|
|
|
228
228
|
### `index conversation`
|
|
229
229
|
|
|
230
|
-
Read and message the personal agent within
|
|
230
|
+
Read and message the personal agent within an intent, or use human DMs.
|
|
231
231
|
|
|
232
232
|
```bash
|
|
233
233
|
index conversation show agent --intent-id <id> --json
|
|
@@ -254,7 +254,7 @@ index onboarding complete [--intent-id <id>] --json
|
|
|
254
254
|
```
|
|
255
255
|
|
|
256
256
|
Confirm a profile only after the owner reviews it. Completion uses the server's
|
|
257
|
-
profile-confirmation and first-
|
|
257
|
+
profile-confirmation and first-intent prerequisites; it does not bypass them.
|
|
258
258
|
For a new account: `profile sync` to see suggested facts, `profile update` to save
|
|
259
259
|
what you approve, `onboarding confirm-profile`, `intent prepare` and `intent create`
|
|
260
260
|
with the returned payload and receipt, then `onboarding complete --intent-id <id>`.
|
|
@@ -298,7 +298,7 @@ fails, without saving partial context.
|
|
|
298
298
|
|
|
299
299
|
## Examples: Reviewing Opportunities
|
|
300
300
|
|
|
301
|
-
Approved
|
|
301
|
+
Approved intents are evaluated in the background. `opportunity list` only reviews persisted results; it does not start evaluation.
|
|
302
302
|
|
|
303
303
|
### Review and act
|
|
304
304
|
|
|
@@ -323,23 +323,23 @@ index opportunity reject <id>
|
|
|
323
323
|
| Flag | Short | Description |
|
|
324
324
|
| -------------------- | ----- | --------------------------------------------------------------- |
|
|
325
325
|
| `--api-url <url>` | | Override API server (default: `https://protocol.index.network`) |
|
|
326
|
-
| `--app-url <url>` | | Override app URL for login (default:
|
|
327
|
-
| `--archived` | | Include archived
|
|
326
|
+
| `--app-url <url>` | | Override the web app URL for login (default: inferred from the API origin) |
|
|
327
|
+
| `--archived` | | Include archived intents (intent list) |
|
|
328
328
|
| `--status <status>` | | Filter opportunities by one pending/accepted/rejected/expired status |
|
|
329
329
|
| `--statuses <list>` | | Comma-separated radar stages, including negotiating |
|
|
330
330
|
| `--limit <n>` | | Positive result limit for intent/opportunity lists or conversation messages |
|
|
331
|
-
| `--prompt <text>` | `-p` | Network description (for `network create`)
|
|
331
|
+
| `--prompt <text>` | `-p` | Network description (for `network create` and `network update`) |
|
|
332
332
|
| `--title <text>` | | Network title (for `network update`) |
|
|
333
333
|
| `--objective <text>` | | Focus objective (for `scrape`) |
|
|
334
|
-
| `--query <text>` | | Match
|
|
335
|
-
| `--intent-id <id>` | | Filter negotiations, scope agent conversations, or select onboarding's first
|
|
334
|
+
| `--query <text>` | | Match intent description and summary text (intent list) |
|
|
335
|
+
| `--intent-id <id>` | | Filter negotiations, scope agent conversations, or select onboarding's first intent |
|
|
336
336
|
| `--state <state>` | | Filter negotiations by `open` or `settled` |
|
|
337
337
|
| `--action <action>` | | Required negotiation turn action: `propose`, `counter`, `accept`, or `decline` |
|
|
338
338
|
| `--message <text>` | | Required message for a negotiation turn |
|
|
339
339
|
| `--expected-turn-count <n>` | | Required observed nonnegative integer turn count for a negotiation turn |
|
|
340
340
|
| `--question-id <id>` | | Identify the displayed question when answering the personal agent |
|
|
341
341
|
| `--answer <key=value>` | | Repeat for recovery prompt labels or agent question IDs |
|
|
342
|
-
| `--receipt <token>` | | Preparation receipt for
|
|
342
|
+
| `--receipt <token>` | | Preparation receipt for intent creation |
|
|
343
343
|
| `--name`, `--intro`, `--location` | | Profile fields to update |
|
|
344
344
|
| `--social <label=value>` | | Repeat to replace profile social links |
|
|
345
345
|
| `--json` | | Output raw JSON to stdout |
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { spawn } from "node:child_process";
|
|
|
5
5
|
// package.json
|
|
6
6
|
var package_default = {
|
|
7
7
|
name: "@indexnetwork/cli",
|
|
8
|
-
version: "0.
|
|
8
|
+
version: "0.29.0",
|
|
9
9
|
description: "Command-line interface for Index Network",
|
|
10
10
|
license: "MIT",
|
|
11
11
|
type: "module",
|
|
@@ -25,10 +25,10 @@ var package_default = {
|
|
|
25
25
|
"publish:all": "bun scripts/publish.ts"
|
|
26
26
|
},
|
|
27
27
|
optionalDependencies: {
|
|
28
|
-
"@indexnetwork/cli-linux-x64": "0.
|
|
29
|
-
"@indexnetwork/cli-linux-arm64": "0.
|
|
30
|
-
"@indexnetwork/cli-darwin-x64": "0.
|
|
31
|
-
"@indexnetwork/cli-darwin-arm64": "0.
|
|
28
|
+
"@indexnetwork/cli-linux-x64": "0.29.0",
|
|
29
|
+
"@indexnetwork/cli-linux-arm64": "0.29.0",
|
|
30
|
+
"@indexnetwork/cli-darwin-x64": "0.29.0",
|
|
31
|
+
"@indexnetwork/cli-darwin-arm64": "0.29.0"
|
|
32
32
|
},
|
|
33
33
|
devDependencies: {
|
|
34
34
|
"@types/bun": "1.3.14"
|
|
@@ -638,7 +638,7 @@ class ApiClient {
|
|
|
638
638
|
return (await this.get(path)).json();
|
|
639
639
|
}
|
|
640
640
|
async getAgent() {
|
|
641
|
-
return (await this.get("/api/agents/me")).json();
|
|
641
|
+
return await (await this.get("/api/agents/me")).json();
|
|
642
642
|
}
|
|
643
643
|
async getNegotiation(opportunityId) {
|
|
644
644
|
const body = await (await this.get(`/api/opportunities/${encodeURIComponent(opportunityId)}/negotiation`)).json();
|
|
@@ -649,13 +649,13 @@ class ApiClient {
|
|
|
649
649
|
return body.negotiation;
|
|
650
650
|
}
|
|
651
651
|
async getAgentConversation(intentId) {
|
|
652
|
-
return (await this.get(`/api/conversations/agent/messages?${new URLSearchParams({ intentId })}`)).json();
|
|
652
|
+
return await (await this.get(`/api/conversations/agent/messages?${new URLSearchParams({ intentId })}`)).json();
|
|
653
653
|
}
|
|
654
654
|
async confirmProfile() {
|
|
655
|
-
return (await this.post("/api/auth/onboarding/confirm-profile", {})).json();
|
|
655
|
+
return await (await this.post("/api/auth/onboarding/confirm-profile", {})).json();
|
|
656
656
|
}
|
|
657
657
|
async completeOnboarding(intentId) {
|
|
658
|
-
return (await this.post("/api/auth/onboarding/complete", { intentId })).json();
|
|
658
|
+
return await (await this.post("/api/auth/onboarding/complete", { intentId })).json();
|
|
659
659
|
}
|
|
660
660
|
async get(path) {
|
|
661
661
|
const res = await fetch(`${this.baseUrl}${path}`, {
|
|
@@ -1085,7 +1085,7 @@ function profileCard(data) {
|
|
|
1085
1085
|
}
|
|
1086
1086
|
function intentTable(intents) {
|
|
1087
1087
|
if (intents.length === 0) {
|
|
1088
|
-
dim(" No
|
|
1088
|
+
dim(" No intents found.");
|
|
1089
1089
|
return;
|
|
1090
1090
|
}
|
|
1091
1091
|
const idWidth = 8;
|
|
@@ -1093,7 +1093,7 @@ function intentTable(intents) {
|
|
|
1093
1093
|
const statusWidth = 10;
|
|
1094
1094
|
const sourceWidth = 16;
|
|
1095
1095
|
const dateWidth = 20;
|
|
1096
|
-
console.log(` ${BOLD}${"ID".padEnd(idWidth)} ${"
|
|
1096
|
+
console.log(` ${BOLD}${"ID".padEnd(idWidth)} ${"Intent".padEnd(descWidth)} ${"Status".padEnd(statusWidth)} ${"Source".padEnd(sourceWidth)} ${"Created".padEnd(dateWidth)}${RESET}`);
|
|
1097
1097
|
console.log(` ${GRAY}${"-".repeat(idWidth)} ${"-".repeat(descWidth)} ${"-".repeat(statusWidth)} ${"-".repeat(sourceWidth)} ${"-".repeat(dateWidth)}${RESET}`);
|
|
1098
1098
|
for (const intent of intents) {
|
|
1099
1099
|
const shortId = intent.id.slice(0, 8);
|
|
@@ -1109,9 +1109,45 @@ function intentTable(intents) {
|
|
|
1109
1109
|
console.log(` ${CYAN}${shortId}${RESET} ${desc.padEnd(descWidth)} ${sColor}${status}${RESET} ${GRAY}${source}${RESET} ${GRAY}${date}${RESET}`);
|
|
1110
1110
|
}
|
|
1111
1111
|
}
|
|
1112
|
+
function intentPreparation(prepared) {
|
|
1113
|
+
if (prepared.status === "ready") {
|
|
1114
|
+
success("Intent is ready to create.");
|
|
1115
|
+
console.log();
|
|
1116
|
+
for (const line of wordWrap(prepared.payload, 72))
|
|
1117
|
+
console.log(` ${line}`);
|
|
1118
|
+
console.log();
|
|
1119
|
+
console.log(` ${BOLD}Create it:${RESET}`);
|
|
1120
|
+
console.log(` index intent create ${shellQuote(prepared.payload)} --receipt ${shellQuote(prepared.preparationReceipt)}`);
|
|
1121
|
+
console.log();
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1124
|
+
console.log();
|
|
1125
|
+
console.log(` ${BOLD}${YELLOW}Needs revision${RESET}`);
|
|
1126
|
+
for (const line of wordWrap(prepared.feedback, 72))
|
|
1127
|
+
console.log(` ${line}`);
|
|
1128
|
+
console.log();
|
|
1129
|
+
console.log(` ${BOLD}Answer these:${RESET}`);
|
|
1130
|
+
for (const field of prepared.recovery) {
|
|
1131
|
+
console.log(` ${CYAN}*${RESET} ${field.label}`);
|
|
1132
|
+
for (const option of field.options ?? []) {
|
|
1133
|
+
const description = option.description ? `${GRAY} — ${option.description}${RESET}` : "";
|
|
1134
|
+
console.log(` ${option.label}${description}`);
|
|
1135
|
+
}
|
|
1136
|
+
if (field.placeholder)
|
|
1137
|
+
console.log(` ${GRAY}${field.placeholder}${RESET}`);
|
|
1138
|
+
}
|
|
1139
|
+
console.log();
|
|
1140
|
+
const answerFlags = prepared.recovery.map((field) => `--answer ${shellQuote(`${field.label}=<reply>`)}`);
|
|
1141
|
+
console.log(` ${BOLD}Then run:${RESET}`);
|
|
1142
|
+
console.log(` index intent prepare ${shellQuote(prepared.payload)} ${answerFlags.join(" ")}`);
|
|
1143
|
+
console.log();
|
|
1144
|
+
}
|
|
1145
|
+
function shellQuote(value) {
|
|
1146
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
1147
|
+
}
|
|
1112
1148
|
function intentCard(intent) {
|
|
1113
1149
|
console.log();
|
|
1114
|
-
console.log(` ${BOLD}${CYAN}
|
|
1150
|
+
console.log(` ${BOLD}${CYAN}Intent Details${RESET}`);
|
|
1115
1151
|
console.log(` ${GRAY}${"─".repeat(50)}${RESET}`);
|
|
1116
1152
|
console.log(` ${BOLD}ID${RESET} ${GRAY}${intent.id}${RESET}`);
|
|
1117
1153
|
console.log(` ${BOLD}Status${RESET} ${intent.status === "ACTIVE" ? GREEN : GRAY}${intent.status}${RESET}`);
|
|
@@ -1262,6 +1298,173 @@ function statusColor(st) {
|
|
|
1262
1298
|
return "";
|
|
1263
1299
|
}
|
|
1264
1300
|
}
|
|
1301
|
+
var ACTION_COLORS = {
|
|
1302
|
+
propose: CYAN,
|
|
1303
|
+
counter: BLUE,
|
|
1304
|
+
accept: GREEN,
|
|
1305
|
+
decline: RED
|
|
1306
|
+
};
|
|
1307
|
+
function shortDateTime(iso) {
|
|
1308
|
+
return new Date(iso).toLocaleString("en-US", {
|
|
1309
|
+
month: "short",
|
|
1310
|
+
day: "numeric",
|
|
1311
|
+
hour: "2-digit",
|
|
1312
|
+
minute: "2-digit"
|
|
1313
|
+
});
|
|
1314
|
+
}
|
|
1315
|
+
function outcomeLabel(outcome) {
|
|
1316
|
+
switch (outcome) {
|
|
1317
|
+
case "agreed":
|
|
1318
|
+
return `${GREEN}agreed${RESET}`;
|
|
1319
|
+
case "declined":
|
|
1320
|
+
return `${RED}declined${RESET}`;
|
|
1321
|
+
case "closed":
|
|
1322
|
+
return `${GRAY}closed${RESET}`;
|
|
1323
|
+
case null:
|
|
1324
|
+
return `${YELLOW}open${RESET}`;
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
function whoseTurn(negotiation) {
|
|
1328
|
+
if (negotiation.awaitingUserId === null)
|
|
1329
|
+
return "nobody";
|
|
1330
|
+
return negotiation.awaitingUserId === negotiation.counterparty.userId ? "them" : "you";
|
|
1331
|
+
}
|
|
1332
|
+
function counterpartyName(negotiation) {
|
|
1333
|
+
return negotiation.counterparty.name ?? "(unnamed)";
|
|
1334
|
+
}
|
|
1335
|
+
function negotiationTable(negotiations) {
|
|
1336
|
+
if (negotiations.length === 0) {
|
|
1337
|
+
dim(" No negotiations found.");
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1340
|
+
const idW = 8;
|
|
1341
|
+
const nameW = 22;
|
|
1342
|
+
const turnsW = 5;
|
|
1343
|
+
const turnW = 10;
|
|
1344
|
+
const outcomeW = 8;
|
|
1345
|
+
const dateW = 12;
|
|
1346
|
+
console.log(` ${BOLD}${"ID".padEnd(idW)} ${"Counterparty".padEnd(nameW)} ${"Turns".padEnd(turnsW)} ${"Whose turn".padEnd(turnW)} ${"Outcome".padEnd(outcomeW)} ${"Updated".padEnd(dateW)}${RESET}`);
|
|
1347
|
+
console.log(` ${GRAY}${"-".repeat(idW)} ${"-".repeat(nameW)} ${"-".repeat(turnsW)} ${"-".repeat(turnW)} ${"-".repeat(outcomeW)} ${"-".repeat(dateW)}${RESET}`);
|
|
1348
|
+
for (const negotiation of negotiations) {
|
|
1349
|
+
const shortId = negotiation.opportunityId.slice(0, idW);
|
|
1350
|
+
const name = counterpartyName(negotiation).slice(0, nameW);
|
|
1351
|
+
const turns = String(negotiation.turnCount);
|
|
1352
|
+
const turn = whoseTurn(negotiation);
|
|
1353
|
+
let turnCell = `${GRAY}${"—".padEnd(turnW)}${RESET}`;
|
|
1354
|
+
if (turn === "you")
|
|
1355
|
+
turnCell = `${YELLOW}${BOLD}${"you".padEnd(turnW)}${RESET}`;
|
|
1356
|
+
if (turn === "them")
|
|
1357
|
+
turnCell = `${GRAY}${"them".padEnd(turnW)}${RESET}`;
|
|
1358
|
+
const outcome = outcomeLabel(negotiation.outcome);
|
|
1359
|
+
const date = new Date(negotiation.updatedAt).toLocaleDateString("en-US", {
|
|
1360
|
+
year: "numeric",
|
|
1361
|
+
month: "short",
|
|
1362
|
+
day: "numeric"
|
|
1363
|
+
});
|
|
1364
|
+
console.log(` ${CYAN}${shortId}${RESET} ${name.padEnd(nameW)} ${turns.padEnd(turnsW)} ${turnCell} ${outcome}${padTo(outcomeW, stripAnsi(outcome))} ${GRAY}${date}${RESET}`);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
function negotiationCard(negotiation) {
|
|
1368
|
+
const name = counterpartyName(negotiation);
|
|
1369
|
+
const rule = ` ${GRAY}${"─".repeat(60)}${RESET}`;
|
|
1370
|
+
let turnLabel = `${GRAY}— settled${RESET}`;
|
|
1371
|
+
if (whoseTurn(negotiation) === "you")
|
|
1372
|
+
turnLabel = `${YELLOW}${BOLD}you${RESET}`;
|
|
1373
|
+
if (whoseTurn(negotiation) === "them")
|
|
1374
|
+
turnLabel = name;
|
|
1375
|
+
console.log();
|
|
1376
|
+
console.log(` ${BOLD}${CYAN}Negotiation with ${name}${RESET}`);
|
|
1377
|
+
console.log(rule);
|
|
1378
|
+
console.log(` ${BOLD}Opportunity${RESET} ${GRAY}${negotiation.opportunityId}${RESET}`);
|
|
1379
|
+
console.log(` ${BOLD}Outcome${RESET} ${outcomeLabel(negotiation.outcome)}`);
|
|
1380
|
+
console.log(` ${BOLD}Turn${RESET} ${negotiation.turnCount} of ${negotiation.protocol.maxTurns}`);
|
|
1381
|
+
console.log(` ${BOLD}Whose turn${RESET} ${turnLabel}`);
|
|
1382
|
+
const [firstLine, ...moreLines] = wordWrap(negotiation.counterparty.statement, 58);
|
|
1383
|
+
console.log(` ${BOLD}Their intent${RESET} ${firstLine}`);
|
|
1384
|
+
for (const line of moreLines)
|
|
1385
|
+
console.log(` ${line}`);
|
|
1386
|
+
console.log();
|
|
1387
|
+
console.log(` ${BOLD}Transcript${RESET}`);
|
|
1388
|
+
if (negotiation.turns.length === 0)
|
|
1389
|
+
console.log(` ${GRAY}No turns yet.${RESET}`);
|
|
1390
|
+
for (const turn of negotiation.turns) {
|
|
1391
|
+
const seat = turn.seatUserId === negotiation.counterparty.userId ? name : "You";
|
|
1392
|
+
console.log(` ${GRAY}${turn.turnIndex + 1}.${RESET} ${BOLD}${seat}${RESET} ${ACTION_COLORS[turn.action]}${turn.action}${RESET} ${GRAY}${shortDateTime(turn.createdAt)}${RESET}`);
|
|
1393
|
+
for (const line of wordWrap(turn.message, 66))
|
|
1394
|
+
console.log(` ${line}`);
|
|
1395
|
+
}
|
|
1396
|
+
const { availableActions, blockedReason, messageLimit } = negotiation.protocol;
|
|
1397
|
+
console.log();
|
|
1398
|
+
if (availableActions.length > 0) {
|
|
1399
|
+
const actions = availableActions.map((action) => `${ACTION_COLORS[action]}${action}${RESET}`).join(", ");
|
|
1400
|
+
console.log(` ${BOLD}Available actions:${RESET} ${actions} ${GRAY}(message up to ${messageLimit} characters)${RESET}`);
|
|
1401
|
+
} else {
|
|
1402
|
+
console.log(` ${BOLD}Available actions:${RESET} ${GRAY}none${RESET}`);
|
|
1403
|
+
}
|
|
1404
|
+
if (blockedReason)
|
|
1405
|
+
console.log(` ${BOLD}Blocked:${RESET} ${YELLOW}${blockedReason}${RESET}`);
|
|
1406
|
+
console.log(rule);
|
|
1407
|
+
if (availableActions.length > 0) {
|
|
1408
|
+
dim(` Reply: index negotiation turn ${negotiation.opportunityId.slice(0, 8)} --action <action> --message <text> --expected-turn-count ${negotiation.turnCount}`);
|
|
1409
|
+
}
|
|
1410
|
+
console.log();
|
|
1411
|
+
}
|
|
1412
|
+
function agentCard(selected) {
|
|
1413
|
+
const { agent, onboardingCompletedAt } = selected;
|
|
1414
|
+
const rule = ` ${GRAY}${"─".repeat(50)}${RESET}`;
|
|
1415
|
+
console.log();
|
|
1416
|
+
console.log(` ${BOLD}${CYAN}${agent.name}${RESET}`);
|
|
1417
|
+
console.log(rule);
|
|
1418
|
+
console.log(` ${BOLD}Seat${RESET} External negotiator (negotiates instead of Index's hosted agent)`);
|
|
1419
|
+
console.log(` ${BOLD}Status${RESET} ${agent.status === "active" ? GREEN : GRAY}${agent.status}${RESET}`);
|
|
1420
|
+
if (agent.description)
|
|
1421
|
+
console.log(` ${BOLD}Description${RESET} ${agent.description}`);
|
|
1422
|
+
console.log(` ${BOLD}Last seen${RESET} ${GRAY}${agent.lastSeenAt ? shortDateTime(agent.lastSeenAt) : "never"}${RESET}`);
|
|
1423
|
+
const onboarding = onboardingCompletedAt ? `${GREEN}complete${RESET} ${GRAY}(${shortDateTime(onboardingCompletedAt)})${RESET}` : `${YELLOW}not complete${RESET}`;
|
|
1424
|
+
console.log(` ${BOLD}Onboarding${RESET} ${onboarding}`);
|
|
1425
|
+
console.log(` ${BOLD}ID${RESET} ${GRAY}${agent.id}${RESET}`);
|
|
1426
|
+
console.log(rule);
|
|
1427
|
+
console.log();
|
|
1428
|
+
}
|
|
1429
|
+
function agentConversation(conversation) {
|
|
1430
|
+
const seat = conversation.agent.status === "hosted" ? "Index's hosted agent" : "your external negotiator";
|
|
1431
|
+
const rule = ` ${GRAY}${"─".repeat(60)}${RESET}`;
|
|
1432
|
+
console.log();
|
|
1433
|
+
console.log(` ${BOLD}${CYAN}Personal agent${RESET} ${GRAY}answered by ${seat}${RESET}`);
|
|
1434
|
+
console.log(rule);
|
|
1435
|
+
if (conversation.messages.length === 0)
|
|
1436
|
+
console.log(` ${GRAY}No messages yet.${RESET}`);
|
|
1437
|
+
for (const message of conversation.messages) {
|
|
1438
|
+
const author = message.role === "user" ? `${BOLD}${CYAN}you${RESET}` : `${BOLD}${BLUE}agent${RESET}`;
|
|
1439
|
+
const text = message.parts.filter((part) => part.kind === "text" && part.text).map((part) => part.text).join(`
|
|
1440
|
+
`);
|
|
1441
|
+
console.log(` ${author} ${GRAY}${shortDateTime(message.createdAt)}${RESET}`);
|
|
1442
|
+
for (const line of wordWrap(text, 70))
|
|
1443
|
+
console.log(` ${line}`);
|
|
1444
|
+
console.log();
|
|
1445
|
+
}
|
|
1446
|
+
const { questions } = conversation.agent;
|
|
1447
|
+
if (questions.length === 0) {
|
|
1448
|
+
console.log(` ${GRAY}No questions waiting for you.${RESET}`);
|
|
1449
|
+
console.log();
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
console.log(` ${BOLD}${YELLOW}Waiting for your answer (${questions.length})${RESET}`);
|
|
1453
|
+
for (const question of questions) {
|
|
1454
|
+
const [firstLine, ...moreLines] = wordWrap(question.question, 66);
|
|
1455
|
+
console.log(` ${YELLOW}?${RESET} ${BOLD}${firstLine}${RESET}`);
|
|
1456
|
+
for (const line of moreLines)
|
|
1457
|
+
console.log(` ${BOLD}${line}${RESET}`);
|
|
1458
|
+
console.log(` ${GRAY}Question ID${RESET} ${CYAN}${question.id}${RESET}`);
|
|
1459
|
+
if (question.options?.length)
|
|
1460
|
+
console.log(` ${GRAY}Options${RESET} ${question.options.join(" / ")}`);
|
|
1461
|
+
if (question.matches.length > 0) {
|
|
1462
|
+
const about = question.matches.map((match) => `${match.counterparty.name ?? "(unnamed)"} ${GRAY}(${match.opportunityId.slice(0, 8)})${RESET}`).join(", ");
|
|
1463
|
+
console.log(` ${GRAY}About${RESET} ${about}`);
|
|
1464
|
+
}
|
|
1465
|
+
console.log();
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1265
1468
|
function networkTable(networks) {
|
|
1266
1469
|
if (networks.length === 0) {
|
|
1267
1470
|
dim(" No networks found.");
|
|
@@ -1468,16 +1671,16 @@ async function profileSync(client, json) {
|
|
|
1468
1671
|
// src/intent.command.ts
|
|
1469
1672
|
var INTENT_HELP = `
|
|
1470
1673
|
Usage:
|
|
1471
|
-
index intent list [--archived] [--limit <n>] [--query <text>] List your
|
|
1472
|
-
index intent show <id> Show
|
|
1674
|
+
index intent list [--archived] [--limit <n>] [--query <text>] List your intents
|
|
1675
|
+
index intent show <id> Show intent details (accepts short ID)
|
|
1473
1676
|
index intent prepare <content> [--answer 'prompt=reply'] Review and repair a draft
|
|
1474
|
-
index intent create <content> [--receipt <token>] Create an admitted
|
|
1677
|
+
index intent create <content> [--receipt <token>] Create an admitted intent
|
|
1475
1678
|
index intent pause <id> | resume <id> Hold or restart its agent
|
|
1476
|
-
index intent update <id> <content> Update
|
|
1477
|
-
index intent archive <id> Archive
|
|
1478
|
-
index intent networks <id> List the networks
|
|
1479
|
-
index intent add-to-network <id> <network-id> Add
|
|
1480
|
-
index intent remove-from-network <id> <network-id> Remove
|
|
1679
|
+
index intent update <id> <content> Update an intent's description
|
|
1680
|
+
index intent archive <id> Archive an intent (accepts short ID)
|
|
1681
|
+
index intent networks <id> List the networks an intent is shared in
|
|
1682
|
+
index intent add-to-network <id> <network-id> Add an intent to a network
|
|
1683
|
+
index intent remove-from-network <id> <network-id> Remove an intent from a network
|
|
1481
1684
|
`;
|
|
1482
1685
|
async function handleIntent(client, subcommand, options) {
|
|
1483
1686
|
if (!subcommand) {
|
|
@@ -1499,7 +1702,7 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1499
1702
|
console.log(JSON.stringify(result));
|
|
1500
1703
|
return;
|
|
1501
1704
|
}
|
|
1502
|
-
heading("
|
|
1705
|
+
heading("Intents");
|
|
1503
1706
|
intentTable(result.intents);
|
|
1504
1707
|
if (result.pagination.totalCount > 0) {
|
|
1505
1708
|
dim(`
|
|
@@ -1510,7 +1713,7 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1510
1713
|
}
|
|
1511
1714
|
case "show": {
|
|
1512
1715
|
if (!options.intentId) {
|
|
1513
|
-
error("Missing
|
|
1716
|
+
error("Missing intent ID. Usage: index intent show <id>", 1);
|
|
1514
1717
|
return;
|
|
1515
1718
|
}
|
|
1516
1719
|
const intent = await client.getIntent(options.intentId);
|
|
@@ -1525,7 +1728,11 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1525
1728
|
if (!options.intentContent)
|
|
1526
1729
|
throw new Error("Usage: index intent prepare <content> [--answer 'prompt=reply']");
|
|
1527
1730
|
const prepared = await client.prepareIntent(options.intentContent, (options.answers ?? []).map(({ key, value }) => ({ prompt: key, answer: value })));
|
|
1528
|
-
|
|
1731
|
+
if (options.json) {
|
|
1732
|
+
console.log(JSON.stringify(prepared));
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
intentPreparation(prepared);
|
|
1529
1736
|
return;
|
|
1530
1737
|
}
|
|
1531
1738
|
case "create": {
|
|
@@ -1534,19 +1741,19 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1534
1741
|
return;
|
|
1535
1742
|
}
|
|
1536
1743
|
if (!options.json)
|
|
1537
|
-
info("Processing
|
|
1744
|
+
info("Processing intent...");
|
|
1538
1745
|
const result = await client.createIntent(options.intentContent, options.targetId ? [options.targetId] : undefined, options.receipt);
|
|
1539
1746
|
if (options.json) {
|
|
1540
1747
|
console.log(JSON.stringify(result));
|
|
1541
1748
|
return;
|
|
1542
1749
|
}
|
|
1543
|
-
success("
|
|
1750
|
+
success("Intent created.");
|
|
1544
1751
|
dim(` shared in ${result.networkIds.length} network${result.networkIds.length === 1 ? "" : "s"}`);
|
|
1545
1752
|
return;
|
|
1546
1753
|
}
|
|
1547
1754
|
case "update": {
|
|
1548
1755
|
if (!options.intentId) {
|
|
1549
|
-
error("Missing
|
|
1756
|
+
error("Missing intent ID. Usage: index intent update <id> <content>", 1);
|
|
1550
1757
|
return;
|
|
1551
1758
|
}
|
|
1552
1759
|
if (!options.intentContent) {
|
|
@@ -1554,13 +1761,13 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1554
1761
|
return;
|
|
1555
1762
|
}
|
|
1556
1763
|
if (!options.json)
|
|
1557
|
-
info("Updating
|
|
1764
|
+
info("Updating intent...");
|
|
1558
1765
|
const result = await client.updateIntent(options.intentId, options.intentContent);
|
|
1559
1766
|
if (options.json) {
|
|
1560
1767
|
console.log(JSON.stringify(result));
|
|
1561
1768
|
return;
|
|
1562
1769
|
}
|
|
1563
|
-
success("
|
|
1770
|
+
success("Intent updated.");
|
|
1564
1771
|
return;
|
|
1565
1772
|
}
|
|
1566
1773
|
case "pause":
|
|
@@ -1572,12 +1779,12 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1572
1779
|
if (options.json)
|
|
1573
1780
|
console.log(JSON.stringify({ intentId: options.intentId, status }));
|
|
1574
1781
|
else
|
|
1575
|
-
success(`
|
|
1782
|
+
success(`Intent ${status.toLowerCase()}.`);
|
|
1576
1783
|
return;
|
|
1577
1784
|
}
|
|
1578
1785
|
case "archive": {
|
|
1579
1786
|
if (!options.intentId) {
|
|
1580
|
-
error("Missing
|
|
1787
|
+
error("Missing intent ID. Usage: index intent archive <id>", 1);
|
|
1581
1788
|
return;
|
|
1582
1789
|
}
|
|
1583
1790
|
await client.archiveIntent(options.intentId);
|
|
@@ -1585,7 +1792,7 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1585
1792
|
console.log(JSON.stringify({ success: true }));
|
|
1586
1793
|
return;
|
|
1587
1794
|
}
|
|
1588
|
-
success(`
|
|
1795
|
+
success(`Intent ${options.intentId} archived.`);
|
|
1589
1796
|
return;
|
|
1590
1797
|
}
|
|
1591
1798
|
case "networks": {
|
|
@@ -1614,7 +1821,7 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1614
1821
|
console.log(JSON.stringify({ success: true }));
|
|
1615
1822
|
return;
|
|
1616
1823
|
}
|
|
1617
|
-
success("
|
|
1824
|
+
success("Intent added to network.");
|
|
1618
1825
|
return;
|
|
1619
1826
|
}
|
|
1620
1827
|
case "remove-from-network": {
|
|
@@ -1627,7 +1834,7 @@ async function handleIntent(client, subcommand, options) {
|
|
|
1627
1834
|
console.log(JSON.stringify({ success: true }));
|
|
1628
1835
|
return;
|
|
1629
1836
|
}
|
|
1630
|
-
success("
|
|
1837
|
+
success("Intent removed from network.");
|
|
1631
1838
|
return;
|
|
1632
1839
|
}
|
|
1633
1840
|
}
|
|
@@ -1724,16 +1931,30 @@ async function opportunityStatusUpdate(client, id, status, json) {
|
|
|
1724
1931
|
|
|
1725
1932
|
// src/negotiation.command.ts
|
|
1726
1933
|
async function handleNegotiation(client, subcommand, options) {
|
|
1727
|
-
let result;
|
|
1728
1934
|
if (subcommand === "list") {
|
|
1729
1935
|
if (options.state !== undefined && options.state !== "open" && options.state !== "settled")
|
|
1730
1936
|
throw new Error("--state must be open or settled");
|
|
1731
|
-
|
|
1937
|
+
const negotiations = await client.listNegotiations({ intentId: options.intentId, state: options.state });
|
|
1938
|
+
if (options.json) {
|
|
1939
|
+
console.log(JSON.stringify(negotiations));
|
|
1940
|
+
return;
|
|
1941
|
+
}
|
|
1942
|
+
heading("Negotiations");
|
|
1943
|
+
negotiationTable(negotiations);
|
|
1944
|
+
if (negotiations.length > 0)
|
|
1945
|
+
dim(`
|
|
1946
|
+
Details: index negotiation show <id> (the short ID works)`);
|
|
1947
|
+
console.log();
|
|
1732
1948
|
} else if (subcommand === "show" || subcommand === "turn") {
|
|
1733
1949
|
if (!options.targetId)
|
|
1734
1950
|
throw new Error("An opportunity ID is required");
|
|
1735
1951
|
if (subcommand === "show") {
|
|
1736
|
-
|
|
1952
|
+
const negotiation = await client.getNegotiation(options.targetId);
|
|
1953
|
+
if (options.json) {
|
|
1954
|
+
console.log(JSON.stringify(negotiation));
|
|
1955
|
+
return;
|
|
1956
|
+
}
|
|
1957
|
+
negotiationCard(negotiation);
|
|
1737
1958
|
} else {
|
|
1738
1959
|
if (!options.action || !["propose", "counter", "accept", "decline"].includes(options.action))
|
|
1739
1960
|
throw new Error("--action must be propose, counter, accept, or decline");
|
|
@@ -1741,16 +1962,21 @@ async function handleNegotiation(client, subcommand, options) {
|
|
|
1741
1962
|
throw new Error("--message is required");
|
|
1742
1963
|
if (options.expectedTurnCount === undefined || !Number.isSafeInteger(options.expectedTurnCount) || options.expectedTurnCount < 0)
|
|
1743
1964
|
throw new Error("--expected-turn-count must be the observed nonnegative integer turn count");
|
|
1744
|
-
|
|
1965
|
+
const negotiation = await client.submitNegotiationTurn(options.targetId, {
|
|
1745
1966
|
action: options.action,
|
|
1746
1967
|
message: options.message,
|
|
1747
1968
|
expectedTurnCount: options.expectedTurnCount
|
|
1748
1969
|
});
|
|
1970
|
+
if (options.json) {
|
|
1971
|
+
console.log(JSON.stringify(negotiation));
|
|
1972
|
+
return;
|
|
1973
|
+
}
|
|
1974
|
+
success(`Turn submitted: ${options.action}`);
|
|
1975
|
+
negotiationCard(negotiation);
|
|
1749
1976
|
}
|
|
1750
1977
|
} else {
|
|
1751
1978
|
throw new Error("Usage: index negotiation list [--intent-id <id>] [--state open|settled], show <opportunity-id>, or turn <opportunity-id> --action <action> --message <text> --expected-turn-count <n>");
|
|
1752
1979
|
}
|
|
1753
|
-
console.log(JSON.stringify(result, null, options.json ? undefined : 2));
|
|
1754
1980
|
}
|
|
1755
1981
|
|
|
1756
1982
|
// src/network.command.ts
|
|
@@ -2030,24 +2256,50 @@ async function handleConversation(client, subcommand, positionals, options) {
|
|
|
2030
2256
|
if (positionals[0] === "agent" && (subcommand === "show" || subcommand === "send")) {
|
|
2031
2257
|
if (!options?.intentId)
|
|
2032
2258
|
throw new Error("Personal-agent conversations require --intent-id <id>");
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2259
|
+
if (subcommand === "show") {
|
|
2260
|
+
const conversation = await client.getAgentConversation(options.intentId);
|
|
2261
|
+
if (options.json) {
|
|
2262
|
+
console.log(JSON.stringify(conversation));
|
|
2263
|
+
return;
|
|
2264
|
+
}
|
|
2265
|
+
agentConversation(conversation);
|
|
2266
|
+
if (conversation.agent.questions.length > 0) {
|
|
2267
|
+
dim(` Answer: index conversation answer agent --intent-id ${options.intentId} --answer '<question-id>=<reply>'`);
|
|
2268
|
+
}
|
|
2269
|
+
return;
|
|
2270
|
+
}
|
|
2271
|
+
const text = positionals.slice(1).join(" ");
|
|
2272
|
+
if (!text.trim())
|
|
2273
|
+
throw new Error("A message is required");
|
|
2274
|
+
if (options.questionId) {
|
|
2275
|
+
const answers = [{ questionId: options.questionId, text }];
|
|
2276
|
+
const result = await client.answerAgentQuestions(options.intentId, answers);
|
|
2277
|
+
if (options.json) {
|
|
2278
|
+
console.log(JSON.stringify(result));
|
|
2279
|
+
return;
|
|
2280
|
+
}
|
|
2281
|
+
printAgentAnswers(answers, result.messages);
|
|
2282
|
+
return;
|
|
2283
|
+
}
|
|
2284
|
+
const message = await client.sendMessage("agent", text, options.intentId);
|
|
2285
|
+
if (options.json) {
|
|
2286
|
+
console.log(JSON.stringify(message));
|
|
2287
|
+
return;
|
|
2288
|
+
}
|
|
2289
|
+
success(`Message sent to your agent (${message.id})`);
|
|
2043
2290
|
return;
|
|
2044
2291
|
}
|
|
2045
2292
|
if (subcommand === "answer") {
|
|
2046
2293
|
if (positionals[0] !== "agent" || !options?.intentId || !options.answers?.length) {
|
|
2047
2294
|
throw new Error("Usage: index conversation answer agent --intent-id <id> --answer 'question-id=text' [--answer ...]");
|
|
2048
2295
|
}
|
|
2049
|
-
const
|
|
2050
|
-
|
|
2296
|
+
const answers = options.answers.map(({ key, value }) => ({ questionId: key, text: value }));
|
|
2297
|
+
const result = await client.answerAgentQuestions(options.intentId, answers);
|
|
2298
|
+
if (options.json) {
|
|
2299
|
+
console.log(JSON.stringify(result));
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
printAgentAnswers(answers, result.messages);
|
|
2051
2303
|
return;
|
|
2052
2304
|
}
|
|
2053
2305
|
if (!subcommand)
|
|
@@ -2075,6 +2327,16 @@ async function handleConversation(client, subcommand, positionals, options) {
|
|
|
2075
2327
|
error(`Unknown conversation subcommand: ${subcommand}`, 1);
|
|
2076
2328
|
}
|
|
2077
2329
|
}
|
|
2330
|
+
function printAgentAnswers(answers, messages) {
|
|
2331
|
+
for (const [index, message] of messages.entries()) {
|
|
2332
|
+
const { questionId } = answers[index];
|
|
2333
|
+
if (message.metadata.principalMessage.kind === "answer") {
|
|
2334
|
+
success(`Answered question ${questionId}`);
|
|
2335
|
+
} else {
|
|
2336
|
+
success(`Question ${questionId} is no longer waiting; your reply was sent to your agent as a message`);
|
|
2337
|
+
}
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2078
2340
|
async function conversationList(client, json) {
|
|
2079
2341
|
const conversations = await client.listConversations();
|
|
2080
2342
|
if (json) {
|
|
@@ -2232,14 +2494,23 @@ async function handleDocs(client, topic, json) {
|
|
|
2232
2494
|
|
|
2233
2495
|
// src/onboarding.command.ts
|
|
2234
2496
|
async function handleOnboarding(client, subcommand, options) {
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2497
|
+
if (subcommand === "confirm-profile") {
|
|
2498
|
+
const result = await client.confirmProfile();
|
|
2499
|
+
if (options?.json) {
|
|
2500
|
+
console.log(JSON.stringify(result));
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
2503
|
+
success("Profile confirmed.");
|
|
2504
|
+
} else if (subcommand === "complete") {
|
|
2505
|
+
const result = await client.completeOnboarding(options?.intentId);
|
|
2506
|
+
if (options?.json) {
|
|
2507
|
+
console.log(JSON.stringify(result));
|
|
2508
|
+
return;
|
|
2509
|
+
}
|
|
2510
|
+
success(`Onboarding complete (first intent ${result.intentId}).`);
|
|
2511
|
+
} else {
|
|
2241
2512
|
throw new Error("Usage: index onboarding confirm-profile | complete [--intent-id <id>]");
|
|
2242
|
-
|
|
2513
|
+
}
|
|
2243
2514
|
}
|
|
2244
2515
|
|
|
2245
2516
|
// src/main.ts
|
|
@@ -2399,11 +2670,17 @@ async function main() {
|
|
|
2399
2670
|
case "docs":
|
|
2400
2671
|
await handleDocs(client, args.positionals?.[0], args.json);
|
|
2401
2672
|
return;
|
|
2402
|
-
case "agent":
|
|
2673
|
+
case "agent": {
|
|
2403
2674
|
if (args.subcommand !== "me")
|
|
2404
2675
|
throw new Error("Usage: index agent me");
|
|
2405
|
-
|
|
2676
|
+
const selected = await client.getAgent();
|
|
2677
|
+
if (args.json) {
|
|
2678
|
+
console.log(JSON.stringify(selected));
|
|
2679
|
+
return;
|
|
2680
|
+
}
|
|
2681
|
+
agentCard(selected);
|
|
2406
2682
|
return;
|
|
2683
|
+
}
|
|
2407
2684
|
case "profile":
|
|
2408
2685
|
await handleProfile(client, args.subcommand, args.subcommand === "search" || args.subcommand === "update" ? args.positionals ?? [] : args.userId ? [args.userId] : [], {
|
|
2409
2686
|
json: args.json,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indexnetwork/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0-rc.88.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.
|
|
24
|
-
"@indexnetwork/cli-linux-arm64": "0.
|
|
25
|
-
"@indexnetwork/cli-darwin-x64": "0.
|
|
26
|
-
"@indexnetwork/cli-darwin-arm64": "0.
|
|
23
|
+
"@indexnetwork/cli-linux-x64": "0.29.0-rc.88.2",
|
|
24
|
+
"@indexnetwork/cli-linux-arm64": "0.29.0-rc.88.2",
|
|
25
|
+
"@indexnetwork/cli-darwin-x64": "0.29.0-rc.88.2",
|
|
26
|
+
"@indexnetwork/cli-darwin-arm64": "0.29.0-rc.88.2"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/bun": "1.3.14"
|