@obol/cli 0.1.3 → 0.2.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.
- package/bin/obol.js +72 -4
- package/package.json +1 -1
- package/src/api.js +11 -0
- package/src/setup.js +195 -22
package/bin/obol.js
CHANGED
|
@@ -4,7 +4,7 @@ import { runSetup } from '../src/setup.js';
|
|
|
4
4
|
import { runStatus } from '../src/status.js';
|
|
5
5
|
import { runConnect } from '../src/connect.js';
|
|
6
6
|
import { runCreditsBuy } from '../src/credits.js';
|
|
7
|
-
import { getBalance, getTiers, createReferralCode, getReferralStats } from '../src/api.js';
|
|
7
|
+
import { getBalance, getTiers, createReferralCode, getReferralStats, listEndpoints, listConnections, refreshToken } from '../src/api.js';
|
|
8
8
|
import { loadEnv } from '../src/config.js';
|
|
9
9
|
import pc from 'picocolors';
|
|
10
10
|
|
|
@@ -41,10 +41,25 @@ async function main() {
|
|
|
41
41
|
console.log(pc.red('\n No agent configured yet. Run: npx @obol/cli setup\n'));
|
|
42
42
|
process.exit(1);
|
|
43
43
|
}
|
|
44
|
+
// Try to refresh the token (in case it's expired)
|
|
45
|
+
let token = env.OBOL_JWT_TOKEN;
|
|
46
|
+
const gwUrl = env.OBOL_GATEWAY_URL || 'https://www.obolagents.com';
|
|
47
|
+
try {
|
|
48
|
+
const data = await refreshToken(gwUrl, token);
|
|
49
|
+
if (data.token) {
|
|
50
|
+
token = data.token;
|
|
51
|
+
// Save refreshed token to .env
|
|
52
|
+
const { saveEnv } = await import('../src/config.js');
|
|
53
|
+
saveEnv({ OBOL_GATEWAY_URL: gwUrl, OBOL_AGENT_ID: env.OBOL_AGENT_ID, OBOL_JWT_TOKEN: token });
|
|
54
|
+
console.log(`\n ${pc.green('Token refreshed!')} Expires: ${pc.dim(new Date(data.expires_at * 1000).toLocaleDateString())}`);
|
|
55
|
+
}
|
|
56
|
+
} catch {
|
|
57
|
+
// Refresh failed — show existing token anyway
|
|
58
|
+
}
|
|
44
59
|
console.log(`\n ${pc.bold('Your Agent Token')}`);
|
|
45
60
|
console.log(` ${pc.dim('Agent:')} ${pc.green(env.OBOL_AGENT_ID || '(unknown)')}`);
|
|
46
61
|
console.log(`\n ${pc.dim('Copy this token and paste it into the dashboard at obolagents.com/dashboard')}`);
|
|
47
|
-
console.log(`\n ${pc.cyan(
|
|
62
|
+
console.log(`\n ${pc.cyan(token)}\n`);
|
|
48
63
|
break;
|
|
49
64
|
}
|
|
50
65
|
|
|
@@ -133,15 +148,68 @@ async function main() {
|
|
|
133
148
|
break;
|
|
134
149
|
}
|
|
135
150
|
|
|
151
|
+
case 'test': {
|
|
152
|
+
const env = loadEnv();
|
|
153
|
+
if (!env.OBOL_GATEWAY_URL || !env.OBOL_JWT_TOKEN) {
|
|
154
|
+
console.log(pc.red('\n No account configured. Run: npx @obol/cli setup\n'));
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
console.log(`\n ${pc.bold('Obol Connection Test')}\n`);
|
|
158
|
+
|
|
159
|
+
// Test gateway connectivity + endpoints
|
|
160
|
+
try {
|
|
161
|
+
const epData = await listEndpoints(env.OBOL_GATEWAY_URL, env.OBOL_JWT_TOKEN);
|
|
162
|
+
const eps = epData.endpoints || [];
|
|
163
|
+
const names = eps.map(e => e.provider || e.name).filter(Boolean);
|
|
164
|
+
console.log(` ${pc.green('✓')} Connection Connected to Obol Gateway`);
|
|
165
|
+
console.log(` ${pc.green('✓')} Account ${pc.bold(env.OBOL_AGENT_ID || '(unknown)')}`);
|
|
166
|
+
console.log(` ${pc.green('✓')} Endpoints ${eps.length} available${names.length ? ` (${names.join(', ')})` : ''}`);
|
|
167
|
+
} catch (err) {
|
|
168
|
+
console.log(` ${pc.red('✗')} Connection ${err.message}`);
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Check balance
|
|
173
|
+
try {
|
|
174
|
+
const bal = await getBalance(env.OBOL_GATEWAY_URL, env.OBOL_JWT_TOKEN);
|
|
175
|
+
const balStr = '$' + (bal.balance_usdc || 0).toFixed(2);
|
|
176
|
+
const color = bal.balance_usdc > 0 ? pc.green : pc.yellow;
|
|
177
|
+
console.log(` ${color(bal.balance_usdc > 0 ? '✓' : '!')} Balance ${color(balStr)} USDC`);
|
|
178
|
+
if (bal.balance_usdc === 0) {
|
|
179
|
+
console.log(`\n ${pc.yellow('Buy credits to start executing:')} ${pc.green('npx @obol/cli credits buy')}`);
|
|
180
|
+
}
|
|
181
|
+
} catch {
|
|
182
|
+
console.log(` ${pc.dim('-')} Balance ${pc.dim('could not fetch')}`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Check connections
|
|
186
|
+
try {
|
|
187
|
+
const connData = await listConnections(env.OBOL_GATEWAY_URL, env.OBOL_JWT_TOKEN);
|
|
188
|
+
const conns = connData.connections || connData || [];
|
|
189
|
+
if (Array.isArray(conns) && conns.length > 0) {
|
|
190
|
+
const connNames = conns.map(c => c.provider).filter(Boolean);
|
|
191
|
+
console.log(` ${pc.green('✓')} Connections ${conns.length} active${connNames.length ? ` (${connNames.join(', ')})` : ''}`);
|
|
192
|
+
} else {
|
|
193
|
+
console.log(` ${pc.dim('-')} Connections none yet`);
|
|
194
|
+
}
|
|
195
|
+
} catch {
|
|
196
|
+
console.log(` ${pc.dim('-')} Connections ${pc.dim('could not fetch')}`);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
console.log();
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
|
|
136
203
|
case 'help':
|
|
137
204
|
case '--help':
|
|
138
205
|
case '-h':
|
|
139
206
|
case undefined:
|
|
140
207
|
console.log(`
|
|
141
|
-
${pc.bold(pc.green('obol'))} —
|
|
208
|
+
${pc.bold(pc.green('obol'))} — Connect your agent to the Obol Execution Gateway
|
|
142
209
|
|
|
143
210
|
${pc.bold('Commands:')}
|
|
144
|
-
${pc.green('setup')}
|
|
211
|
+
${pc.green('setup')} Connect your agent to Obol (interactive wizard)
|
|
212
|
+
${pc.green('test')} Verify your Obol connection is working
|
|
145
213
|
${pc.green('status')} Check agent health, balance & connections
|
|
146
214
|
${pc.green('token')} Show your JWT token (for the dashboard)
|
|
147
215
|
${pc.green('connect')} ${pc.dim('<provider>')} Add a service API key (github, slack, etc.)
|
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -146,8 +146,19 @@ export async function validateReferralCode(gatewayUrl, code) {
|
|
|
146
146
|
});
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
+
export async function listEndpoints(gatewayUrl, jwt) {
|
|
150
|
+
return request(`${gatewayUrl}/v1/endpoints`, { headers: jwtHeaders(jwt) });
|
|
151
|
+
}
|
|
152
|
+
|
|
149
153
|
export async function getAgentInfo(gatewayUrl, adminKey, agentId) {
|
|
150
154
|
return request(`${gatewayUrl}/v1/agents/${agentId}`, {
|
|
151
155
|
headers: adminHeaders(adminKey),
|
|
152
156
|
});
|
|
153
157
|
}
|
|
158
|
+
|
|
159
|
+
export async function refreshToken(gatewayUrl, jwt) {
|
|
160
|
+
return request(`${gatewayUrl}/v1/token/refresh`, {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
headers: jwtHeaders(jwt),
|
|
163
|
+
});
|
|
164
|
+
}
|
package/src/setup.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
1
4
|
import * as p from '@clack/prompts';
|
|
2
5
|
import pc from 'picocolors';
|
|
3
|
-
import { checkHealth, signup, storeBYOK, validateReferralCode } from './api.js';
|
|
6
|
+
import { checkHealth, signup, storeBYOK, validateReferralCode, listEndpoints } from './api.js';
|
|
4
7
|
import { saveEnv } from './config.js';
|
|
5
8
|
|
|
6
9
|
const cheers = ['Nice!', 'Boom!', "Let's go.", 'Easy.', 'Done.'];
|
|
@@ -10,7 +13,7 @@ export async function runSetup() {
|
|
|
10
13
|
console.log();
|
|
11
14
|
p.intro(pc.bgGreen(pc.black(' Welcome to Obol! ')));
|
|
12
15
|
|
|
13
|
-
p.log.info("Let's
|
|
16
|
+
p.log.info("Let's connect your agent to Obol. Takes about 60 seconds.");
|
|
14
17
|
|
|
15
18
|
const url = 'https://www.obolagents.com';
|
|
16
19
|
|
|
@@ -28,12 +31,12 @@ export async function runSetup() {
|
|
|
28
31
|
process.exit(1);
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
// ---
|
|
34
|
+
// --- Account Name ---
|
|
32
35
|
const agentId = await p.text({
|
|
33
|
-
message: 'Pick a name for your
|
|
36
|
+
message: 'Pick a name for your Obol account',
|
|
34
37
|
placeholder: 'my-agent',
|
|
35
38
|
validate: (val) => {
|
|
36
|
-
if (!val) return 'Your
|
|
39
|
+
if (!val) return 'Your account needs a name!';
|
|
37
40
|
if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]{1,62}[a-zA-Z0-9]$/.test(val)) {
|
|
38
41
|
return 'Letters, numbers, hyphens, and underscores only (3-64 chars)';
|
|
39
42
|
}
|
|
@@ -122,8 +125,8 @@ export async function runSetup() {
|
|
|
122
125
|
// --- Confirm ---
|
|
123
126
|
const keyCount = Object.keys(apiKeys).length;
|
|
124
127
|
const confirmMsg = keyCount
|
|
125
|
-
? `Create
|
|
126
|
-
: `Create
|
|
128
|
+
? `Create Obol account ${pc.bold(pc.green(agentId))} with ${services.length} service${services.length > 1 ? 's' : ''} and ${keyCount} API key${keyCount > 1 ? 's' : ''}?`
|
|
129
|
+
: `Create Obol account ${pc.bold(pc.green(agentId))} with ${services.length} service${services.length > 1 ? 's' : ''}?`;
|
|
127
130
|
const confirmed = await p.confirm({ message: confirmMsg });
|
|
128
131
|
if (p.isCancel(confirmed) || !confirmed) return cancelled();
|
|
129
132
|
|
|
@@ -131,8 +134,8 @@ export async function runSetup() {
|
|
|
131
134
|
console.log();
|
|
132
135
|
const s = p.spinner();
|
|
133
136
|
|
|
134
|
-
// 1. Sign up
|
|
135
|
-
s.start('Creating your
|
|
137
|
+
// 1. Sign up
|
|
138
|
+
s.start('Creating your account...');
|
|
136
139
|
let jwt;
|
|
137
140
|
let expiresAt;
|
|
138
141
|
try {
|
|
@@ -141,17 +144,17 @@ export async function runSetup() {
|
|
|
141
144
|
expiresAt = new Date(result.expires_at * 1000);
|
|
142
145
|
|
|
143
146
|
if (result.referral) {
|
|
144
|
-
s.stop(pc.green(`
|
|
147
|
+
s.stop(pc.green(`Account "${agentId}" created with referral! $${result.referral.signup_bonus_referee} bonus unlocks after your first API call `) + cheer());
|
|
145
148
|
} else {
|
|
146
|
-
s.stop(pc.green(`
|
|
149
|
+
s.stop(pc.green(`Account "${agentId}" created! `) + cheer());
|
|
147
150
|
}
|
|
148
151
|
} catch (err) {
|
|
149
152
|
if (err.status === 409) {
|
|
150
|
-
s.stop(pc.red(`
|
|
153
|
+
s.stop(pc.red(`That account name was revoked — try a different name.`));
|
|
151
154
|
} else {
|
|
152
|
-
s.stop(pc.red(`Couldn't create
|
|
155
|
+
s.stop(pc.red(`Couldn't create account: ${err.message}`));
|
|
153
156
|
}
|
|
154
|
-
p.outro(pc.dim('Try again
|
|
157
|
+
p.outro(pc.dim('Try again.'));
|
|
155
158
|
process.exit(1);
|
|
156
159
|
}
|
|
157
160
|
|
|
@@ -178,23 +181,193 @@ export async function runSetup() {
|
|
|
178
181
|
const envPath = saveEnv(vars);
|
|
179
182
|
s.stop(pc.green(`Saved to ${envPath}`));
|
|
180
183
|
|
|
181
|
-
//
|
|
184
|
+
// 4. Detect project type and install SDK
|
|
185
|
+
let lang = detectProject();
|
|
186
|
+
let sdkInstalled = false;
|
|
187
|
+
let integrationFile = null;
|
|
188
|
+
|
|
189
|
+
if (!lang) {
|
|
190
|
+
lang = await p.select({
|
|
191
|
+
message: 'What language is your agent built in?',
|
|
192
|
+
options: [
|
|
193
|
+
{ value: 'js', label: 'JavaScript / TypeScript' },
|
|
194
|
+
{ value: 'python', label: 'Python' },
|
|
195
|
+
],
|
|
196
|
+
});
|
|
197
|
+
if (p.isCancel(lang)) return cancelled();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const hasPackageJson = existsSync(resolve(process.cwd(), 'package.json'));
|
|
201
|
+
|
|
202
|
+
if (lang === 'js') {
|
|
203
|
+
if (hasPackageJson) {
|
|
204
|
+
s.start('Installing @obol/sdk...');
|
|
205
|
+
try {
|
|
206
|
+
execSync('npm install @obol/sdk', { stdio: 'pipe', timeout: 60000 });
|
|
207
|
+
s.stop(pc.green('SDK installed! ') + cheer());
|
|
208
|
+
sdkInstalled = true;
|
|
209
|
+
} catch {
|
|
210
|
+
s.stop(pc.yellow('Could not auto-install SDK. Run manually: npm install @obol/sdk'));
|
|
211
|
+
}
|
|
212
|
+
} else {
|
|
213
|
+
p.log.info(`Install the SDK when you're ready: ${pc.green('npm install @obol/sdk')}`);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Generate integration file
|
|
217
|
+
const obolFile = resolve(process.cwd(), 'obol.js');
|
|
218
|
+
if (!existsSync(obolFile)) {
|
|
219
|
+
s.start('Generating integration file...');
|
|
220
|
+
writeFileSync(obolFile, jsIntegrationFile(agentId, services));
|
|
221
|
+
s.stop(pc.green('Created obol.js'));
|
|
222
|
+
integrationFile = 'obol.js';
|
|
223
|
+
}
|
|
224
|
+
} else if (lang === 'python') {
|
|
225
|
+
s.start('Installing obol-sdk...');
|
|
226
|
+
try {
|
|
227
|
+
execSync('pip install obol-sdk', { stdio: 'pipe', timeout: 60000 });
|
|
228
|
+
s.stop(pc.green('SDK installed! ') + cheer());
|
|
229
|
+
sdkInstalled = true;
|
|
230
|
+
} catch {
|
|
231
|
+
s.stop(pc.yellow('Could not auto-install SDK. Run manually: pip install obol-sdk'));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Generate integration file
|
|
235
|
+
const obolFile = resolve(process.cwd(), 'obol_setup.py');
|
|
236
|
+
if (!existsSync(obolFile)) {
|
|
237
|
+
s.start('Generating integration file...');
|
|
238
|
+
writeFileSync(obolFile, pyIntegrationFile(agentId, services));
|
|
239
|
+
s.stop(pc.green('Created obol_setup.py'));
|
|
240
|
+
integrationFile = 'obol_setup.py';
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 5. Test connectivity
|
|
245
|
+
s.start('Testing connection...');
|
|
246
|
+
try {
|
|
247
|
+
const epData = await listEndpoints(url, jwt);
|
|
248
|
+
const eps = epData.endpoints || [];
|
|
249
|
+
const names = eps.map(e => e.provider || e.name).filter(Boolean);
|
|
250
|
+
s.stop(pc.green(`Connected! ${eps.length} endpoints available`) + (names.length ? ` (${names.join(', ')})` : ''));
|
|
251
|
+
} catch {
|
|
252
|
+
s.stop(pc.yellow('Could not verify connection — run obol test later to check'));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// --- Summary ---
|
|
256
|
+
console.log();
|
|
257
|
+
p.log.success(pc.bold(`Your agent is connected to Obol!`));
|
|
182
258
|
console.log();
|
|
183
|
-
|
|
259
|
+
|
|
260
|
+
if (sdkInstalled) {
|
|
261
|
+
console.log(` ${pc.dim('SDK installed:')} ${pc.green(lang === 'js' ? '@obol/sdk' : 'obol-sdk')}`);
|
|
262
|
+
}
|
|
263
|
+
if (integrationFile) {
|
|
264
|
+
console.log(` ${pc.dim('Integration file:')} ${pc.green('./' + integrationFile)}`);
|
|
265
|
+
}
|
|
266
|
+
console.log(` ${pc.dim('Config saved:')} ${pc.green(envPath)}`);
|
|
267
|
+
console.log();
|
|
268
|
+
|
|
269
|
+
// Prominent $0 balance warning
|
|
270
|
+
p.log.warn(pc.bold(pc.yellow('Your balance is $0.00 — you need credits before your agent can execute.')));
|
|
184
271
|
console.log();
|
|
185
272
|
|
|
186
|
-
console.log(` ${pc.
|
|
187
|
-
console.log(`
|
|
188
|
-
console.log(`
|
|
189
|
-
|
|
273
|
+
console.log(` ${pc.bold('Next steps:')}`);
|
|
274
|
+
console.log(` ${pc.dim('1.')} ${pc.bold('Buy credits')} ${pc.dim('(required)')}: ${pc.green('npx @obol/cli credits buy')}`);
|
|
275
|
+
console.log(` ${pc.dim('or visit:')} ${pc.cyan('obolagents.com/dashboard')}`);
|
|
276
|
+
if (lang === 'js' && integrationFile) {
|
|
277
|
+
console.log(` ${pc.dim('2.')} Use in your code:`);
|
|
278
|
+
console.log(` ${pc.cyan("import { obol } from './obol.js';")}`);
|
|
279
|
+
console.log(` ${pc.cyan("const result = await obol.execute(2, 'Create issue ...');")}`);
|
|
280
|
+
} else if (lang === 'python' && integrationFile) {
|
|
281
|
+
console.log(` ${pc.dim('2.')} Use in your code:`);
|
|
282
|
+
console.log(` ${pc.cyan("from obol_setup import obol")}`);
|
|
283
|
+
console.log(` ${pc.cyan("result = obol.execute(2, 'Create issue ...', idempotency_key='...')")}`);
|
|
284
|
+
}
|
|
285
|
+
console.log();
|
|
286
|
+
console.log(` ${pc.dim('Dashboard:')} ${pc.green('npx @obol/cli token')} → paste at ${pc.cyan('obolagents.com/dashboard')}`);
|
|
287
|
+
console.log(` ${pc.dim('Token:')} Refreshes automatically — run ${pc.green('npx @obol/cli test')} anytime to verify.`);
|
|
190
288
|
console.log();
|
|
191
|
-
|
|
192
|
-
p.log.info(pc.
|
|
289
|
+
|
|
290
|
+
p.log.info(`${pc.bold('Earn credits by referring other agents!')} Run ${pc.green('npx @obol/cli referral code')} to get started.`);
|
|
193
291
|
console.log();
|
|
194
292
|
|
|
195
293
|
p.outro('Go build something awesome. ' + pc.green('⚡'));
|
|
196
294
|
}
|
|
197
295
|
|
|
296
|
+
function detectProject() {
|
|
297
|
+
const cwd = process.cwd();
|
|
298
|
+
if (existsSync(resolve(cwd, 'package.json'))) return 'js';
|
|
299
|
+
if (existsSync(resolve(cwd, 'requirements.txt'))) return 'python';
|
|
300
|
+
if (existsSync(resolve(cwd, 'pyproject.toml'))) return 'python';
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function jsIntegrationFile(agentId, services) {
|
|
305
|
+
const providerMap = { stripe: 1, github: 2, slack: 3, notion: 4, discord: 5, twitter: 6, agentmail: 7 };
|
|
306
|
+
const examples = services
|
|
307
|
+
.map(svc => {
|
|
308
|
+
const id = providerMap[svc];
|
|
309
|
+
const ex = {
|
|
310
|
+
stripe: `await obol.execute(${id}, 'Create invoice for $50 to customer@example.com');`,
|
|
311
|
+
github: `await obol.execute(${id}, 'Create issue titled "Bug report" in owner/repo');`,
|
|
312
|
+
slack: `await obol.execute(${id}, 'Send message "Hello team" to #general');`,
|
|
313
|
+
notion: `await obol.execute(${id}, 'Create page titled "Meeting Notes"');`,
|
|
314
|
+
discord: `await obol.execute(${id}, 'Send message "Hello" to channel 123456');`,
|
|
315
|
+
twitter: `await obol.execute(${id}, 'Post tweet: Just shipped a new feature!');`,
|
|
316
|
+
agentmail: `await obol.execute(${id}, 'Send email to user@example.com subject "Hello"');`,
|
|
317
|
+
};
|
|
318
|
+
return `// ${ex[svc] || `await obol.execute(${id}, 'your intent here');`}`;
|
|
319
|
+
})
|
|
320
|
+
.join('\n');
|
|
321
|
+
|
|
322
|
+
return `import { ObolClient } from '@obol/sdk';
|
|
323
|
+
|
|
324
|
+
// Pre-configured Obol client — reads OBOL_JWT_TOKEN from .env automatically
|
|
325
|
+
export const obol = new ObolClient();
|
|
326
|
+
|
|
327
|
+
// Provider IDs: 1=Stripe, 2=GitHub, 3=Slack, 4=Notion, 5=Discord, 6=Twitter, 7=AgentMail
|
|
328
|
+
//
|
|
329
|
+
// Usage:
|
|
330
|
+
// import { obol } from './obol.js';
|
|
331
|
+
${examples}
|
|
332
|
+
`;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
function pyIntegrationFile(agentId, services) {
|
|
336
|
+
const providerMap = { stripe: 1, github: 2, slack: 3, notion: 4, discord: 5, twitter: 6, agentmail: 7 };
|
|
337
|
+
const examples = services
|
|
338
|
+
.map(svc => {
|
|
339
|
+
const id = providerMap[svc];
|
|
340
|
+
const ex = {
|
|
341
|
+
stripe: `# obol.execute(${id}, 'Create invoice for $50 to customer@example.com', idempotency_key='unique-key')`,
|
|
342
|
+
github: `# obol.execute(${id}, 'Create issue titled "Bug report" in owner/repo', idempotency_key='unique-key')`,
|
|
343
|
+
slack: `# obol.execute(${id}, 'Send message "Hello team" to #general', idempotency_key='unique-key')`,
|
|
344
|
+
notion: `# obol.execute(${id}, 'Create page titled "Meeting Notes"', idempotency_key='unique-key')`,
|
|
345
|
+
discord: `# obol.execute(${id}, 'Send message "Hello" to channel 123456', idempotency_key='unique-key')`,
|
|
346
|
+
twitter: `# obol.execute(${id}, 'Post tweet: Just shipped a new feature!', idempotency_key='unique-key')`,
|
|
347
|
+
agentmail: `# obol.execute(${id}, 'Send email to user@example.com subject "Hello"', idempotency_key='unique-key')`,
|
|
348
|
+
};
|
|
349
|
+
return ex[svc] || `# obol.execute(${id}, 'your intent here', idempotency_key='unique-key')`;
|
|
350
|
+
})
|
|
351
|
+
.join('\n');
|
|
352
|
+
|
|
353
|
+
return `import os
|
|
354
|
+
from obol_sdk import ObolClient
|
|
355
|
+
|
|
356
|
+
# Pre-configured Obol client — reads from environment variables
|
|
357
|
+
obol = ObolClient(
|
|
358
|
+
gateway_url=os.getenv("OBOL_GATEWAY_URL", "https://www.obolagents.com"),
|
|
359
|
+
agent_id=os.getenv("OBOL_AGENT_ID", "${agentId}"),
|
|
360
|
+
jwt_token=os.getenv("OBOL_JWT_TOKEN", ""),
|
|
361
|
+
)
|
|
362
|
+
|
|
363
|
+
# Provider IDs: 1=Stripe, 2=GitHub, 3=Slack, 4=Notion, 5=Discord, 6=Twitter, 7=AgentMail
|
|
364
|
+
#
|
|
365
|
+
# Usage:
|
|
366
|
+
# from obol_setup import obol
|
|
367
|
+
${examples}
|
|
368
|
+
`;
|
|
369
|
+
}
|
|
370
|
+
|
|
198
371
|
function cancelled() {
|
|
199
372
|
p.cancel('Setup cancelled. Come back anytime!');
|
|
200
373
|
process.exit(0);
|