context-markets-cli 0.1.0

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.
@@ -0,0 +1,199 @@
1
+ import {
2
+ tradingClient
3
+ } from "./chunk-BUZKJ7FR.js";
4
+ import {
5
+ fail,
6
+ getOutputMode,
7
+ out,
8
+ requirePositional
9
+ } from "./chunk-QC6BGRUQ.js";
10
+
11
+ // src/commands/questions.ts
12
+ import chalk from "chalk";
13
+ var HELP = `Usage: context questions <subcommand> [options]
14
+
15
+ Subcommands:
16
+ submit <question> Submit a question for AI market generation
17
+ status <submissionId> Check status of a question submission
18
+ submit-and-wait <question> Submit and poll until complete
19
+ --poll-interval <ms> Poll interval in ms (default: 2000)
20
+ --max-attempts <n> Max poll attempts (default: 45)
21
+ agent-submit Submit a fully-formed market draft directly
22
+ --formatted-question <text> Full question text (required)
23
+ --short-question <text> Short display title (required)
24
+ --market-type <type> SUBJECTIVE or OBJECTIVE (required)
25
+ --evidence-mode <mode> social_only or web_enabled (required)
26
+ --resolution-criteria <text> How the market should resolve (required)
27
+ --end-time <datetime> End time as "YYYY-MM-DD HH:MM:SS" (required)
28
+ --timezone <tz> IANA timezone (default: America/New_York)
29
+ --sources <urls> Comma-separated source URLs
30
+ --explanation <text> Brief explanation (max 120 chars)
31
+ agent-submit-and-wait Same as agent-submit but polls until complete
32
+ (same flags as agent-submit, plus:)
33
+ --poll-interval <ms> Poll interval in ms (default: 2000)
34
+ --max-attempts <n> Max poll attempts (default: 45)
35
+
36
+ help Show this help text
37
+
38
+ Global options:
39
+ --api-key <key> Context API key (or CONTEXT_API_KEY env)
40
+ --private-key <key> Private key for signing (or CONTEXT_PRIVATE_KEY env)`;
41
+ async function handleQuestions(parsed) {
42
+ const { subcommand, positional, flags } = parsed;
43
+ switch (subcommand) {
44
+ case "submit":
45
+ return submit(positional, flags);
46
+ case "status":
47
+ return status(positional, flags);
48
+ case "submit-and-wait":
49
+ return submitAndWait(positional, flags);
50
+ case "agent-submit":
51
+ return agentSubmit(positional, flags);
52
+ case "agent-submit-and-wait":
53
+ return agentSubmitAndWait(positional, flags);
54
+ case "help":
55
+ case void 0:
56
+ console.log(HELP);
57
+ return;
58
+ default:
59
+ fail(`Unknown questions subcommand: "${subcommand}". Run "context questions help" for usage.`);
60
+ }
61
+ }
62
+ function submissionDetail(r) {
63
+ const questions = r.questions || [];
64
+ const similarMarkets = r.similarMarkets || [];
65
+ const rejections = r.rejectionReasons || [];
66
+ return [
67
+ ["Submission ID", String(r.submissionId || "\u2014")],
68
+ ["Status", String(r.status || "\u2014")],
69
+ ...questions.flatMap((q, i) => [
70
+ [`Question ${i + 1}`, q.text || "\u2014"],
71
+ [` Market ID`, q.id]
72
+ ]),
73
+ ...r.statusUpdates?.length ? [["Latest Update", String(r.statusUpdates.at(-1)?.status || "\u2014")]] : [],
74
+ ...similarMarkets.flatMap((m, i) => [
75
+ [`Similar ${i + 1}`, `${m.shortQuestion || m.question} (${Math.round(m.similarity * 100)}% match)`],
76
+ [` Market ID`, m.id]
77
+ ]),
78
+ ...rejections.map((r2) => [`Rejected`, `[${r2.code}] ${r2.message}`]),
79
+ ...r.qualityExplanation ? [["Quality", String(r.qualityExplanation)]] : [],
80
+ ...r.refuseToResolve ? [["Warning", "Marked as unresolvable"]] : [],
81
+ ...r.appliedChanges?.length ? r.appliedChanges.map((c) => ["Change Applied", c]) : []
82
+ ];
83
+ }
84
+ async function submit(positional, flags) {
85
+ const question = requirePositional(positional, 0, "question", "context questions submit <question>");
86
+ const ctx = tradingClient(flags);
87
+ const result = await ctx.questions.submit(question);
88
+ const r = result;
89
+ out(result, {
90
+ detail: [
91
+ ["Submission ID", String(r.id || r.submissionId || "\u2014")],
92
+ ["Status", String(r.status || "\u2014")]
93
+ ]
94
+ });
95
+ }
96
+ async function status(positional, flags) {
97
+ const submissionId = requirePositional(positional, 0, "submissionId", "context questions status <submissionId>");
98
+ const ctx = tradingClient(flags);
99
+ const result = await ctx.questions.getSubmission(submissionId);
100
+ const r = result;
101
+ out(result, { detail: submissionDetail(r) });
102
+ }
103
+ async function submitAndWait(positional, flags) {
104
+ const question = requirePositional(positional, 0, "question", "context questions submit-and-wait <question>");
105
+ const ctx = tradingClient(flags);
106
+ const opts = {
107
+ pollIntervalMs: flags["poll-interval"] ? parseInt(flags["poll-interval"], 10) : void 0,
108
+ maxAttempts: flags["max-attempts"] ? parseInt(flags["max-attempts"], 10) : void 0
109
+ };
110
+ let result;
111
+ if (getOutputMode() === "table") {
112
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
113
+ let i = 0;
114
+ const timer = setInterval(() => {
115
+ process.stderr.write(`\r${chalk.cyan(frames[i++ % frames.length])} Submitting question and waiting for AI generation...`);
116
+ }, 80);
117
+ try {
118
+ result = await ctx.questions.submitAndWait(question, opts);
119
+ clearInterval(timer);
120
+ process.stderr.write(`\r${chalk.green("\u2713")} Question processed!
121
+ `);
122
+ } catch (err) {
123
+ clearInterval(timer);
124
+ process.stderr.write(`\r${chalk.red("\u2717")} Failed.
125
+ `);
126
+ throw err;
127
+ }
128
+ } else {
129
+ result = await ctx.questions.submitAndWait(question, opts);
130
+ }
131
+ out(result, { detail: submissionDetail(result) });
132
+ }
133
+ function parseAgentSubmitFlags(flags) {
134
+ const formattedQuestion = flags["formatted-question"];
135
+ const shortQuestion = flags["short-question"];
136
+ const marketType = flags["market-type"];
137
+ const evidenceMode = flags["evidence-mode"];
138
+ const resolutionCriteria = flags["resolution-criteria"];
139
+ const endTime = flags["end-time"];
140
+ if (!formattedQuestion || !shortQuestion || !marketType || !evidenceMode || !resolutionCriteria || !endTime) {
141
+ fail("Required flags: --formatted-question, --short-question, --market-type, --evidence-mode, --resolution-criteria, --end-time");
142
+ }
143
+ return {
144
+ market: {
145
+ formattedQuestion,
146
+ shortQuestion,
147
+ marketType,
148
+ evidenceMode,
149
+ resolutionCriteria,
150
+ endTime,
151
+ timezone: flags["timezone"] || "America/New_York",
152
+ sources: flags["sources"] ? flags["sources"].split(",").map((s) => s.trim()) : void 0,
153
+ explanation: flags["explanation"]
154
+ }
155
+ };
156
+ }
157
+ async function agentSubmit(positional, flags) {
158
+ const draft = parseAgentSubmitFlags(flags);
159
+ const ctx = tradingClient(flags);
160
+ const result = await ctx.questions.agentSubmit(draft);
161
+ out(result, {
162
+ detail: [
163
+ ["Submission ID", String(result.submissionId || "\u2014")]
164
+ ]
165
+ });
166
+ }
167
+ async function agentSubmitAndWait(positional, flags) {
168
+ const draft = parseAgentSubmitFlags(flags);
169
+ const ctx = tradingClient(flags);
170
+ const opts = {
171
+ pollIntervalMs: flags["poll-interval"] ? parseInt(flags["poll-interval"], 10) : void 0,
172
+ maxAttempts: flags["max-attempts"] ? parseInt(flags["max-attempts"], 10) : void 0
173
+ };
174
+ let result;
175
+ if (getOutputMode() === "table") {
176
+ const frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
177
+ let i = 0;
178
+ const timer = setInterval(() => {
179
+ process.stderr.write(`\r${chalk.cyan(frames[i++ % frames.length])} Submitting market draft and waiting for processing...`);
180
+ }, 80);
181
+ try {
182
+ result = await ctx.questions.agentSubmitAndWait(draft, opts);
183
+ clearInterval(timer);
184
+ process.stderr.write(`\r${chalk.green("\u2713")} Market draft processed!
185
+ `);
186
+ } catch (err) {
187
+ clearInterval(timer);
188
+ process.stderr.write(`\r${chalk.red("\u2717")} Failed.
189
+ `);
190
+ throw err;
191
+ }
192
+ } else {
193
+ result = await ctx.questions.agentSubmitAndWait(draft, opts);
194
+ }
195
+ out(result, { detail: submissionDetail(result) });
196
+ }
197
+ export {
198
+ handleQuestions as default
199
+ };
@@ -0,0 +1,230 @@
1
+ import {
2
+ tradingClient
3
+ } from "./chunk-BUZKJ7FR.js";
4
+ import {
5
+ fail,
6
+ getOutputMode,
7
+ out,
8
+ requirePositional
9
+ } from "./chunk-QC6BGRUQ.js";
10
+
11
+ // src/commands/setup.ts
12
+ import * as p from "@clack/prompts";
13
+ import chalk from "chalk";
14
+ import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
15
+ async function handleSetup(parsed) {
16
+ const { subcommand, positional, flags } = parsed;
17
+ switch (subcommand) {
18
+ case "setup":
19
+ return setup(flags);
20
+ case "approve":
21
+ return approve(flags);
22
+ case "deposit":
23
+ return deposit(positional, flags);
24
+ case "gasless-approve":
25
+ return gaslessApprove(flags);
26
+ case "gasless-deposit":
27
+ return gaslessDeposit(positional, flags);
28
+ default:
29
+ fail(`Unknown setup subcommand: "${subcommand}"`);
30
+ }
31
+ }
32
+ async function setup(flags) {
33
+ const privateKey = flags["private-key"] ?? process.env.CONTEXT_PRIVATE_KEY;
34
+ if (getOutputMode() === "json") {
35
+ if (!privateKey) {
36
+ const newKey = generatePrivateKey();
37
+ const account = privateKeyToAccount(newKey);
38
+ out({
39
+ status: "new_wallet",
40
+ address: account.address,
41
+ privateKey: newKey,
42
+ nextSteps: [
43
+ "Save the private key securely \u2014 it cannot be recovered.",
44
+ "Export it: export CONTEXT_PRIVATE_KEY=<key>",
45
+ "Fund the wallet with testnet ETH and USDC on Base Sepolia.",
46
+ "Run `context approve` to approve contracts for trading.",
47
+ "Run `context deposit <amount>` to deposit USDC into the exchange."
48
+ ]
49
+ });
50
+ return;
51
+ }
52
+ const ctx = tradingClient(flags);
53
+ const walletStatus = await ctx.account.status();
54
+ out({
55
+ status: "existing_wallet",
56
+ ...walletStatus,
57
+ nextSteps: walletStatus.needsApprovals ? [
58
+ "Run `context approve` to approve contracts.",
59
+ "Run `context deposit <amount>` to deposit."
60
+ ] : ["Wallet is fully set up. You can start trading."]
61
+ });
62
+ return;
63
+ }
64
+ p.intro(chalk.bold("Context Markets \u2014 Setup"));
65
+ if (privateKey) {
66
+ const account = privateKeyToAccount(privateKey);
67
+ p.log.success(
68
+ `Wallet detected from ${flags["private-key"] ? "--private-key flag" : "CONTEXT_PRIVATE_KEY env"}`
69
+ );
70
+ p.log.info(`Address: ${account.address}`);
71
+ const ctx = tradingClient(flags);
72
+ const status = await ctx.account.status();
73
+ if (status.needsApprovals) {
74
+ const doApprove = await p.confirm({
75
+ message: "Approve contracts for trading? (gasless)"
76
+ });
77
+ if (p.isCancel(doApprove)) {
78
+ p.outro("Setup cancelled.");
79
+ process.exit(0);
80
+ }
81
+ if (doApprove) {
82
+ const s = p.spinner();
83
+ s.start("Approving contracts...");
84
+ await ctx.account.gaslessSetup();
85
+ s.stop("Contracts approved");
86
+ }
87
+ } else {
88
+ p.log.success("Contracts already approved");
89
+ }
90
+ const doMint = await p.confirm({
91
+ message: "Mint test USDC? (1000 USDC)"
92
+ });
93
+ if (p.isCancel(doMint)) {
94
+ p.outro("Setup cancelled.");
95
+ process.exit(0);
96
+ }
97
+ if (doMint) {
98
+ const s = p.spinner();
99
+ s.start("Minting test USDC...");
100
+ await ctx.account.mintTestUsdc(1e3);
101
+ s.stop("Minted 1,000 USDC");
102
+ }
103
+ const doDeposit = await p.confirm({
104
+ message: "Deposit USDC to start trading?"
105
+ });
106
+ if (p.isCancel(doDeposit)) {
107
+ p.outro("Setup cancelled.");
108
+ process.exit(0);
109
+ }
110
+ if (doDeposit) {
111
+ const amount = await p.text({
112
+ message: "Enter amount to deposit:",
113
+ placeholder: "500",
114
+ validate: (v = "") => {
115
+ const n = parseFloat(v);
116
+ if (isNaN(n) || n <= 0) return "Must be a positive number";
117
+ }
118
+ });
119
+ if (p.isCancel(amount)) {
120
+ p.outro("Setup cancelled.");
121
+ process.exit(0);
122
+ }
123
+ const s = p.spinner();
124
+ s.start("Depositing USDC...");
125
+ await ctx.account.gaslessDeposit(parseFloat(amount));
126
+ s.stop(`Deposited $${parseFloat(amount).toFixed(2)} USDC`);
127
+ }
128
+ p.outro(chalk.green("Setup complete! You're ready to trade."));
129
+ } else {
130
+ const hasKey = await p.select({
131
+ message: "Do you have an existing private key?",
132
+ options: [
133
+ { value: "no", label: "No, generate one" },
134
+ { value: "yes", label: "Yes, import one" }
135
+ ]
136
+ });
137
+ if (p.isCancel(hasKey)) {
138
+ p.outro("Setup cancelled.");
139
+ process.exit(0);
140
+ }
141
+ if (hasKey === "yes") {
142
+ const key = await p.text({
143
+ message: "Enter your private key:",
144
+ placeholder: "0x...",
145
+ validate: (v = "") => {
146
+ if (!v.startsWith("0x") || v.length !== 66)
147
+ return "Invalid private key format (must be 0x + 64 hex chars)";
148
+ }
149
+ });
150
+ if (p.isCancel(key)) {
151
+ p.outro("Setup cancelled.");
152
+ process.exit(0);
153
+ }
154
+ const account = privateKeyToAccount(key);
155
+ p.log.success("Wallet imported");
156
+ p.log.info(`Address: ${account.address}`);
157
+ p.log.warning(`Set your key: export CONTEXT_PRIVATE_KEY="${key}"`);
158
+ } else {
159
+ const newKey = generatePrivateKey();
160
+ const account = privateKeyToAccount(newKey);
161
+ p.log.success("Wallet created");
162
+ p.log.info(`Address: ${account.address}`);
163
+ p.log.warning("Back up your private key! It cannot be recovered.");
164
+ p.log.info(`export CONTEXT_PRIVATE_KEY="${newKey}"`);
165
+ }
166
+ p.outro("Set CONTEXT_PRIVATE_KEY and re-run `context setup` to continue.");
167
+ }
168
+ console.log();
169
+ console.log(chalk.dim(" Next steps:"));
170
+ console.log(chalk.dim(" context markets list Browse markets"));
171
+ console.log(chalk.dim(" context guides trading Learn to trade"));
172
+ console.log(chalk.dim(" context shell Interactive mode"));
173
+ console.log();
174
+ }
175
+ async function approve(flags) {
176
+ const ctx = tradingClient(flags);
177
+ const result = await ctx.account.setup();
178
+ const walletStatus = await ctx.account.status();
179
+ out({
180
+ status: "approved",
181
+ usdcApprovalTx: result.usdcApprovalTx,
182
+ operatorApprovalTx: result.operatorApprovalTx,
183
+ wallet: walletStatus,
184
+ nextSteps: [
185
+ "Run `context deposit <amount>` to deposit USDC into the exchange."
186
+ ]
187
+ });
188
+ }
189
+ async function deposit(positional, flags) {
190
+ const raw = requirePositional(
191
+ positional,
192
+ 0,
193
+ "amount",
194
+ "context deposit <amount>"
195
+ );
196
+ const amount = parseFloat(raw);
197
+ if (isNaN(amount) || amount <= 0) {
198
+ fail("Deposit amount must be a positive number.", { received: raw });
199
+ }
200
+ const ctx = tradingClient(flags);
201
+ const txHash = await ctx.account.deposit(amount);
202
+ out({
203
+ status: "deposited",
204
+ amount,
205
+ txHash
206
+ });
207
+ }
208
+ async function gaslessApprove(flags) {
209
+ const ctx = tradingClient(flags);
210
+ const result = await ctx.account.gaslessSetup();
211
+ out(result);
212
+ }
213
+ async function gaslessDeposit(positional, flags) {
214
+ const raw = requirePositional(
215
+ positional,
216
+ 0,
217
+ "amount",
218
+ "context gasless-deposit <amount>"
219
+ );
220
+ const amount = parseFloat(raw);
221
+ if (isNaN(amount) || amount <= 0) {
222
+ fail("Deposit amount must be a positive number.", { received: raw });
223
+ }
224
+ const ctx = tradingClient(flags);
225
+ const result = await ctx.account.gaslessDeposit(amount);
226
+ out(result);
227
+ }
228
+ export {
229
+ handleSetup as default
230
+ };
@@ -0,0 +1,203 @@
1
+ import {
2
+ setShellReadline
3
+ } from "./chunk-BJIFIOK6.js";
4
+ import {
5
+ onResults,
6
+ parseArgs,
7
+ setOutputMode
8
+ } from "./chunk-QC6BGRUQ.js";
9
+
10
+ // src/shell.ts
11
+ import * as readline from "readline";
12
+ import chalk from "chalk";
13
+ var lastResults = [];
14
+ var lastCursor = null;
15
+ var lastCommand = null;
16
+ function resolveRefs(input) {
17
+ return input.replace(/#(\d+)/g, (match, num) => {
18
+ const idx = parseInt(num, 10) - 1;
19
+ const item = lastResults[idx];
20
+ if (!item) return match;
21
+ const id = item.id || item.marketId || item.nonce;
22
+ return id ? String(id) : match;
23
+ });
24
+ }
25
+ function splitArgs(input) {
26
+ const args = [];
27
+ let current = "";
28
+ let inQuote = false;
29
+ let quoteChar = "";
30
+ for (const ch of input) {
31
+ if (inQuote) {
32
+ if (ch === quoteChar) {
33
+ inQuote = false;
34
+ } else {
35
+ current += ch;
36
+ }
37
+ } else if (ch === '"' || ch === "'") {
38
+ inQuote = true;
39
+ quoteChar = ch;
40
+ } else if (ch === " " || ch === " ") {
41
+ if (current) {
42
+ args.push(current);
43
+ current = "";
44
+ }
45
+ } else {
46
+ current += ch;
47
+ }
48
+ }
49
+ if (current) args.push(current);
50
+ return args;
51
+ }
52
+ var BANNER = [
53
+ " \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
54
+ " \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551 \u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D \u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D",
55
+ " \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 ",
56
+ " \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551 ",
57
+ " \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2554\u255D \u2588\u2588\u2557 \u2588\u2588\u2551 ",
58
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D "
59
+ ];
60
+ var GRADIENT = [
61
+ "#a78bfa",
62
+ // violet-400
63
+ "#818cf8",
64
+ // indigo-400
65
+ "#6366f1",
66
+ // indigo-500
67
+ "#4f46e5",
68
+ // indigo-600
69
+ "#4338ca",
70
+ // indigo-700
71
+ "#3730a3"
72
+ // indigo-800
73
+ ];
74
+ async function runShell() {
75
+ console.log();
76
+ for (let i = 0; i < BANNER.length; i++) {
77
+ console.log(chalk.hex(GRADIENT[i])(BANNER[i]));
78
+ }
79
+ console.log();
80
+ console.log(chalk.bold(" Prediction Markets") + chalk.dim(" \xB7 Interactive Shell"));
81
+ console.log(chalk.dim(" Type 'help' for commands, 'exit' to quit."));
82
+ console.log();
83
+ setOutputMode({ output: "table" });
84
+ onResults((items, cursor) => {
85
+ lastResults = items;
86
+ lastCursor = cursor || null;
87
+ });
88
+ const rl = readline.createInterface({
89
+ input: process.stdin,
90
+ output: process.stdout,
91
+ prompt: chalk.dim("context> "),
92
+ terminal: true
93
+ });
94
+ setShellReadline(rl);
95
+ rl.prompt();
96
+ rl.on("line", async (line) => {
97
+ const trimmed = line.trim();
98
+ if (!trimmed) {
99
+ rl.prompt();
100
+ return;
101
+ }
102
+ if (trimmed === "exit" || trimmed === "quit") {
103
+ console.log(chalk.dim("Goodbye!"));
104
+ rl.close();
105
+ process.exit(0);
106
+ }
107
+ if (trimmed === "help") {
108
+ console.log();
109
+ console.log(chalk.bold(" Commands:"));
110
+ console.log(" markets <subcommand> Browse and search markets");
111
+ console.log(" orders <subcommand> Manage orders");
112
+ console.log(" portfolio <subcommand> View positions and balances");
113
+ console.log(" account <subcommand> Wallet and account operations");
114
+ console.log(" questions <subcommand> Submit questions for AI markets");
115
+ console.log(" guides [topic] View usage guides");
116
+ console.log();
117
+ console.log(chalk.bold(" Shell features:"));
118
+ console.log(" #N Reference row N from last result");
119
+ console.log(" next Load next page of last result");
120
+ console.log(" exit / quit Leave the shell");
121
+ console.log();
122
+ rl.prompt();
123
+ return;
124
+ }
125
+ let commandLine = trimmed;
126
+ if (trimmed === "next") {
127
+ if (!lastCommand || !lastCursor) {
128
+ console.log(chalk.dim(" No previous paginated result."));
129
+ rl.prompt();
130
+ return;
131
+ }
132
+ commandLine = `${lastCommand} --cursor ${lastCursor}`;
133
+ }
134
+ commandLine = resolveRefs(commandLine);
135
+ if (commandLine.startsWith("setup")) {
136
+ console.log(chalk.dim(" Run 'context setup' outside the shell."));
137
+ rl.prompt();
138
+ return;
139
+ }
140
+ if (commandLine.startsWith("shell")) {
141
+ console.log(chalk.dim(" Already in shell mode."));
142
+ rl.prompt();
143
+ return;
144
+ }
145
+ lastCommand = commandLine.replace(/\s+--cursor\s+\S+/g, "");
146
+ const argv = ["bun", "cli.ts", ...splitArgs(commandLine)];
147
+ const parsed = parseArgs(argv);
148
+ try {
149
+ switch (parsed.command) {
150
+ case "markets": {
151
+ const mod = await import("./markets-WZCKLKJR.js");
152
+ await mod.default(parsed);
153
+ break;
154
+ }
155
+ case "orders": {
156
+ const mod = await import("./orders-IA2XKE5J.js");
157
+ await mod.default(parsed);
158
+ break;
159
+ }
160
+ case "portfolio": {
161
+ const mod = await import("./portfolio-73RM2RAQ.js");
162
+ await mod.default(parsed);
163
+ break;
164
+ }
165
+ case "account": {
166
+ const mod = await import("./account-DL4WGQCC.js");
167
+ await mod.default(parsed);
168
+ break;
169
+ }
170
+ case "questions": {
171
+ const mod = await import("./questions-P6AUM6D4.js");
172
+ await mod.default(parsed);
173
+ break;
174
+ }
175
+ case "guides": {
176
+ const mod = await import("./guides-Y2YWEZCY.js");
177
+ await mod.default(parsed);
178
+ break;
179
+ }
180
+ default:
181
+ console.log(
182
+ chalk.dim(
183
+ ` Unknown command: "${parsed.command}". Type 'help' for commands.`
184
+ )
185
+ );
186
+ }
187
+ } catch (err) {
188
+ if (err instanceof Error && (err.name === "CancelError" || err.name === "FailError")) {
189
+ } else {
190
+ const message = err instanceof Error ? err.message : String(err);
191
+ console.error(chalk.red(` Error: ${message}`));
192
+ }
193
+ }
194
+ console.log();
195
+ rl.prompt();
196
+ });
197
+ rl.on("close", () => {
198
+ process.exit(0);
199
+ });
200
+ }
201
+ export {
202
+ runShell
203
+ };
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "context-markets-cli",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "CLI for trading on Context prediction markets",
6
+ "author": "Context",
7
+ "license": "MIT",
8
+ "homepage": "https://docs.context.markets/agents/cli",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/contextwtf/context-cli.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/contextwtf/context-cli/issues"
15
+ },
16
+ "keywords": [
17
+ "prediction-markets",
18
+ "context",
19
+ "cli",
20
+ "trading",
21
+ "web3",
22
+ "blockchain"
23
+ ],
24
+ "engines": {
25
+ "node": ">=18"
26
+ },
27
+ "main": "dist/cli.js",
28
+ "bin": {
29
+ "context": "dist/cli.js"
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "README.md",
34
+ "LICENSE"
35
+ ],
36
+ "scripts": {
37
+ "build": "tsup src/cli.ts --format esm --dts --outDir dist",
38
+ "test": "bun test"
39
+ },
40
+ "dependencies": {
41
+ "@clack/prompts": "^1.0.1",
42
+ "context-markets": "^0.4.0",
43
+ "chalk": "^5.6.2",
44
+ "cli-table3": "^0.6.5",
45
+ "viem": "^2.23.2"
46
+ },
47
+ "devDependencies": {
48
+ "@types/bun": "latest",
49
+ "tsup": "^8.0.0"
50
+ }
51
+ }