@obolos_tech/cli 0.3.3 → 0.5.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.
Files changed (72) hide show
  1. package/README.md +35 -1
  2. package/dist/commands/anp.d.ts +277 -0
  3. package/dist/commands/anp.js +440 -0
  4. package/dist/commands/anp.js.map +1 -0
  5. package/dist/commands/index.d.ts +3 -0
  6. package/dist/commands/index.js +34 -0
  7. package/dist/commands/index.js.map +1 -0
  8. package/dist/commands/jobs.d.ts +111 -0
  9. package/dist/commands/jobs.js +294 -0
  10. package/dist/commands/jobs.js.map +1 -0
  11. package/dist/commands/listings.d.ts +128 -0
  12. package/dist/commands/listings.js +246 -0
  13. package/dist/commands/listings.js.map +1 -0
  14. package/dist/commands/marketplace.d.ts +87 -0
  15. package/dist/commands/marketplace.js +133 -0
  16. package/dist/commands/marketplace.js.map +1 -0
  17. package/dist/commands/reputation.d.ts +27 -0
  18. package/dist/commands/reputation.js +114 -0
  19. package/dist/commands/reputation.js.map +1 -0
  20. package/dist/commands/setup.d.ts +78 -0
  21. package/dist/commands/setup.js +133 -0
  22. package/dist/commands/setup.js.map +1 -0
  23. package/dist/commands/wallet.d.ts +30 -0
  24. package/dist/commands/wallet.js +66 -0
  25. package/dist/commands/wallet.js.map +1 -0
  26. package/dist/index.d.ts +4 -24
  27. package/dist/index.js +61 -2516
  28. package/dist/index.js.map +1 -1
  29. package/dist/registry.d.ts +53 -0
  30. package/dist/registry.js +39 -0
  31. package/dist/registry.js.map +1 -0
  32. package/dist/runtime/acp.d.ts +162 -0
  33. package/dist/runtime/acp.js +132 -0
  34. package/dist/runtime/acp.js.map +1 -0
  35. package/dist/runtime/anp.d.ts +214 -0
  36. package/dist/runtime/anp.js +255 -0
  37. package/dist/runtime/anp.js.map +1 -0
  38. package/dist/runtime/argv.d.ts +18 -0
  39. package/dist/runtime/argv.js +114 -0
  40. package/dist/runtime/argv.js.map +1 -0
  41. package/dist/runtime/config.d.ts +14 -0
  42. package/dist/runtime/config.js +34 -0
  43. package/dist/runtime/config.js.map +1 -0
  44. package/dist/runtime/dispatch.d.ts +13 -0
  45. package/dist/runtime/dispatch.js +123 -0
  46. package/dist/runtime/dispatch.js.map +1 -0
  47. package/dist/runtime/display.d.ts +21 -0
  48. package/dist/runtime/display.js +68 -0
  49. package/dist/runtime/display.js.map +1 -0
  50. package/dist/runtime/errors.d.ts +19 -0
  51. package/dist/runtime/errors.js +23 -0
  52. package/dist/runtime/errors.js.map +1 -0
  53. package/dist/runtime/http.d.ts +9 -0
  54. package/dist/runtime/http.js +36 -0
  55. package/dist/runtime/http.js.map +1 -0
  56. package/dist/runtime/output.d.ts +19 -0
  57. package/dist/runtime/output.js +12 -0
  58. package/dist/runtime/output.js.map +1 -0
  59. package/dist/runtime/payment.d.ts +21 -0
  60. package/dist/runtime/payment.js +91 -0
  61. package/dist/runtime/payment.js.map +1 -0
  62. package/dist/runtime/wallet.d.ts +32 -0
  63. package/dist/runtime/wallet.js +44 -0
  64. package/dist/runtime/wallet.js.map +1 -0
  65. package/dist/schema/json-schema.d.ts +10 -0
  66. package/dist/schema/json-schema.js +34 -0
  67. package/dist/schema/json-schema.js.map +1 -0
  68. package/dist/schema/zod-shape.d.ts +9 -0
  69. package/dist/schema/zod-shape.js +36 -0
  70. package/dist/schema/zod-shape.js.map +1 -0
  71. package/package.json +46 -4
  72. package/scripts/lint-stdout-purity.mjs +62 -0
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Parse argv against an InputSchema. Supports:
3
+ * --flag value
4
+ * --flag=value
5
+ * -a value (via field.alias)
6
+ * positional args (via field.positional index)
7
+ * --flag (boolean)
8
+ *
9
+ * Returns a typed input object + leftover tokens (e.g. the trailing `--` bag).
10
+ */
11
+ import { userError } from './errors.js';
12
+ export function parseArgs(schema, argv) {
13
+ const flags = {};
14
+ const positionals = [];
15
+ let json = false;
16
+ let help = false;
17
+ let dryRun = false;
18
+ for (let i = 0; i < argv.length; i++) {
19
+ const tok = argv[i];
20
+ if (tok === '--json') {
21
+ json = true;
22
+ continue;
23
+ }
24
+ if (tok === '--help' || tok === '-h') {
25
+ help = true;
26
+ continue;
27
+ }
28
+ if (tok === '--dry-run') {
29
+ dryRun = true;
30
+ continue;
31
+ }
32
+ if (tok.startsWith('--')) {
33
+ const eq = tok.indexOf('=');
34
+ if (eq !== -1) {
35
+ flags[tok.slice(2, eq)] = tok.slice(eq + 1);
36
+ }
37
+ else {
38
+ const name = tok.slice(2);
39
+ const next = argv[i + 1];
40
+ if (next !== undefined && !next.startsWith('--')) {
41
+ flags[name] = next;
42
+ i++;
43
+ }
44
+ else {
45
+ flags[name] = true;
46
+ }
47
+ }
48
+ continue;
49
+ }
50
+ if (tok.startsWith('-') && tok.length === 2) {
51
+ const short = tok.slice(1);
52
+ const name = Object.keys(schema).find(k => schema[k].alias === short);
53
+ if (!name)
54
+ throw userError(`Unknown flag: ${tok}`);
55
+ const next = argv[i + 1];
56
+ if (schema[name].type === 'boolean') {
57
+ flags[name] = true;
58
+ }
59
+ else if (next !== undefined && !next.startsWith('-')) {
60
+ flags[name] = next;
61
+ i++;
62
+ }
63
+ else {
64
+ throw userError(`Flag ${tok} requires a value`);
65
+ }
66
+ continue;
67
+ }
68
+ positionals.push(tok);
69
+ }
70
+ const input = {};
71
+ for (const [name, field] of Object.entries(schema)) {
72
+ let raw;
73
+ if (field.positional !== undefined) {
74
+ raw = positionals[field.positional];
75
+ }
76
+ else {
77
+ raw = flags[name];
78
+ }
79
+ if (raw === undefined) {
80
+ if (field.required && !help)
81
+ throw userError(`Missing required: ${field.positional !== undefined ? name : `--${name}`}`);
82
+ if (field.default !== undefined)
83
+ input[name] = field.default;
84
+ continue;
85
+ }
86
+ input[name] = coerce(name, field.type, raw, field.enum);
87
+ }
88
+ return { input, json, help, dryRun };
89
+ }
90
+ function coerce(name, type, raw, enums) {
91
+ if (type === 'boolean')
92
+ return raw === true || raw === 'true';
93
+ if (type === 'number') {
94
+ const n = Number(raw);
95
+ if (Number.isNaN(n))
96
+ throw userError(`--${name} must be a number, got: ${String(raw)}`);
97
+ return n;
98
+ }
99
+ if (type === 'json') {
100
+ if (typeof raw !== 'string')
101
+ throw userError(`--${name} must be a JSON string`);
102
+ try {
103
+ return JSON.parse(raw);
104
+ }
105
+ catch {
106
+ throw userError(`--${name} is not valid JSON`);
107
+ }
108
+ }
109
+ const s = String(raw);
110
+ if (enums && !enums.includes(s))
111
+ throw userError(`--${name} must be one of: ${enums.join(', ')}`);
112
+ return s;
113
+ }
114
+ //# sourceMappingURL=argv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argv.js","sourceRoot":"","sources":["../../src/runtime/argv.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Config resolution: env vars > ~/.obolos/config.json > defaults.
3
+ * Kept schema-compatible with @obolos_tech/mcp-server so both binaries
4
+ * read the same config file written by `obolos setup`.
5
+ */
6
+ export declare const CONFIG_DIR: string;
7
+ export declare const CONFIG_FILE: string;
8
+ export interface ObolosConfig {
9
+ apiUrl: string;
10
+ privateKey: string | null;
11
+ walletAddress: string | null;
12
+ }
13
+ export declare function loadConfig(): ObolosConfig;
14
+ export declare function writeConfigPatch(patch: Record<string, string>): void;
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Config resolution: env vars > ~/.obolos/config.json > defaults.
3
+ * Kept schema-compatible with @obolos_tech/mcp-server so both binaries
4
+ * read the same config file written by `obolos setup`.
5
+ */
6
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
7
+ import { homedir } from 'os';
8
+ import { join } from 'path';
9
+ export const CONFIG_DIR = join(homedir(), '.obolos');
10
+ export const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
11
+ function readFile() {
12
+ try {
13
+ if (existsSync(CONFIG_FILE))
14
+ return JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));
15
+ }
16
+ catch { }
17
+ return {};
18
+ }
19
+ export function loadConfig() {
20
+ const file = readFile();
21
+ return {
22
+ apiUrl: process.env.OBOLOS_API_URL || file.api_url || 'https://obolos.tech',
23
+ privateKey: process.env.OBOLOS_PRIVATE_KEY || file.private_key || null,
24
+ walletAddress: file.wallet_address || null,
25
+ };
26
+ }
27
+ export function writeConfigPatch(patch) {
28
+ const current = readFile();
29
+ const merged = { ...current, ...patch };
30
+ if (!existsSync(CONFIG_DIR))
31
+ mkdirSync(CONFIG_DIR, { mode: 0o700 });
32
+ writeFileSync(CONFIG_FILE, JSON.stringify(merged, null, 2) + '\n', { mode: 0o600 });
33
+ }
34
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/runtime/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACrD,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAQ3D,SAAS,QAAQ;IACf,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,WAAW,CAAC;YAAE,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IACV,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,CAAC,OAAO,IAAI,qBAAqB;QAC3E,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI;QACtE,aAAa,EAAE,IAAI,CAAC,cAAc,IAAI,IAAI;KAC3C,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAA6B;IAC5D,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;IAC3B,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;IACxC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtF,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Dispatcher: look up a command by name/alias, parse its argv against the
3
+ * schema, build a RunContext, run, then render with format() or JSON.
4
+ *
5
+ * Returns { handled: true, exitCode } when the registry owns the command;
6
+ * returns { handled: false } so the legacy switch in index.ts can handle
7
+ * commands that haven't been ported yet.
8
+ */
9
+ export interface DispatchResult {
10
+ handled: boolean;
11
+ exitCode?: number;
12
+ }
13
+ export declare function dispatch(command: string, argv: string[]): Promise<DispatchResult>;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Dispatcher: look up a command by name/alias, parse its argv against the
3
+ * schema, build a RunContext, run, then render with format() or JSON.
4
+ *
5
+ * Returns { handled: true, exitCode } when the registry owns the command;
6
+ * returns { handled: false } so the legacy switch in index.ts can handle
7
+ * commands that haven't been ported yet.
8
+ */
9
+ import { registry } from '../commands/index.js';
10
+ import { parseArgs } from './argv.js';
11
+ import { loadConfig } from './config.js';
12
+ import { createHttpClient } from './http.js';
13
+ import { renderJson } from './output.js';
14
+ import { CliError } from './errors.js';
15
+ import { toJsonSchema } from '../schema/json-schema.js';
16
+ export async function dispatch(command, argv) {
17
+ // Try `group.sub` first if the first argv token is not a flag.
18
+ // Lets us route `obolos reputation check 42` → reputation.check with argv ["42"].
19
+ let cmd = registry.resolve(command);
20
+ let remaining = argv;
21
+ if (argv[0] && !argv[0].startsWith('-')) {
22
+ const combined = `${command}.${argv[0]}`;
23
+ const grouped = registry.resolve(combined);
24
+ if (grouped) {
25
+ cmd = grouped;
26
+ remaining = argv.slice(1);
27
+ }
28
+ else if (command === 'rep' || command === 'reputation') {
29
+ const aliased = registry.resolve(`reputation.${argv[0]}`);
30
+ if (aliased) {
31
+ cmd = aliased;
32
+ remaining = argv.slice(1);
33
+ }
34
+ }
35
+ else if (command === 'j' || command === 'job') {
36
+ const aliased = registry.resolve(`job.${argv[0]}`);
37
+ if (aliased) {
38
+ cmd = aliased;
39
+ remaining = argv.slice(1);
40
+ }
41
+ }
42
+ else if (command === 'l' || command === 'listing') {
43
+ const aliased = registry.resolve(`listing.${argv[0]}`);
44
+ if (aliased) {
45
+ cmd = aliased;
46
+ remaining = argv.slice(1);
47
+ }
48
+ }
49
+ else if (command === 'anp') {
50
+ const aliased = registry.resolve(`anp.${argv[0]}`);
51
+ if (aliased) {
52
+ cmd = aliased;
53
+ remaining = argv.slice(1);
54
+ }
55
+ }
56
+ }
57
+ if (!cmd)
58
+ return { handled: false };
59
+ argv = remaining;
60
+ try {
61
+ const parsed = parseArgs(cmd.input, argv);
62
+ if (parsed.help) {
63
+ process.stdout.write(renderHelp(cmd) + '\n');
64
+ return { handled: true, exitCode: 0 };
65
+ }
66
+ const config = loadConfig();
67
+ const ctx = {
68
+ config,
69
+ http: createHttpClient(config.apiUrl),
70
+ source: 'cli',
71
+ json: parsed.json,
72
+ dryRun: parsed.dryRun,
73
+ };
74
+ const output = await cmd.run(parsed.input, ctx);
75
+ if (parsed.json || !cmd.format) {
76
+ process.stdout.write(renderJson(output) + '\n');
77
+ }
78
+ else {
79
+ process.stdout.write(cmd.format(output, ctx) + '\n');
80
+ }
81
+ return { handled: true, exitCode: 0 };
82
+ }
83
+ catch (err) {
84
+ if (err instanceof CliError) {
85
+ process.stderr.write(`Error: ${err.message}\n`);
86
+ return { handled: true, exitCode: err.code };
87
+ }
88
+ throw err;
89
+ }
90
+ }
91
+ function renderHelp(cmd) {
92
+ const lines = [
93
+ `obolos ${cmd.name} — ${cmd.summary}`,
94
+ '',
95
+ ];
96
+ if (cmd.description)
97
+ lines.push(cmd.description, '');
98
+ const fields = Object.entries(cmd.input);
99
+ if (fields.length > 0) {
100
+ lines.push('Arguments:');
101
+ for (const [name, field] of fields) {
102
+ const prefix = field.positional !== undefined ? ` <${name}>` : ` --${name}`;
103
+ const req = field.required ? ' (required)' : '';
104
+ const def = field.default !== undefined ? ` [default: ${JSON.stringify(field.default)}]` : '';
105
+ const en = field.enum ? ` (${field.enum.join('|')})` : '';
106
+ lines.push(`${prefix.padEnd(24)} ${field.description}${req}${def}${en}`);
107
+ }
108
+ lines.push('');
109
+ }
110
+ lines.push('Options:');
111
+ lines.push(' --json Machine-readable output');
112
+ lines.push(' --dry-run Preview destructive actions without executing');
113
+ lines.push(' -h, --help Show this help');
114
+ if (cmd.examples?.length) {
115
+ lines.push('', 'Examples:');
116
+ for (const ex of cmd.examples)
117
+ lines.push(` ${ex}`);
118
+ }
119
+ lines.push('', 'JSON schema (for MCP / scripting):');
120
+ lines.push(JSON.stringify(toJsonSchema(cmd.input), null, 2));
121
+ return lines.join('\n');
122
+ }
123
+ //# sourceMappingURL=dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../src/runtime/dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Shared formatting helpers for pretty output.
3
+ */
4
+ export declare const c: {
5
+ reset: string;
6
+ bold: string;
7
+ dim: string;
8
+ green: string;
9
+ yellow: string;
10
+ blue: string;
11
+ magenta: string;
12
+ cyan: string;
13
+ red: string;
14
+ gray: string;
15
+ };
16
+ export declare function shortenAddr(addr: string | undefined | null): string;
17
+ export declare function shortenId(id: string): string;
18
+ export declare function formatDate(iso: string | undefined | null): string;
19
+ export declare function statusColor(status: string): string;
20
+ export declare function parseRelativeTime(input: string): string;
21
+ export declare function parseTimeToSeconds(input: string): number;
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Shared formatting helpers for pretty output.
3
+ */
4
+ export const c = {
5
+ reset: '\x1b[0m', bold: '\x1b[1m', dim: '\x1b[2m',
6
+ green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', magenta: '\x1b[35m',
7
+ cyan: '\x1b[36m', red: '\x1b[31m', gray: '\x1b[90m',
8
+ };
9
+ export function shortenAddr(addr) {
10
+ if (!addr)
11
+ return `${c.dim}—${c.reset}`;
12
+ if (addr.length <= 12)
13
+ return addr;
14
+ return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
15
+ }
16
+ export function shortenId(id) {
17
+ return id.length <= 12 ? id : `${id.slice(0, 8)}...`;
18
+ }
19
+ export function formatDate(iso) {
20
+ if (!iso)
21
+ return `${c.dim}—${c.reset}`;
22
+ const d = new Date(iso);
23
+ return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
24
+ }
25
+ export function statusColor(status) {
26
+ switch (status) {
27
+ case 'open': return `${c.yellow}${status}${c.reset}`;
28
+ case 'funded': return `${c.blue}${status}${c.reset}`;
29
+ case 'submitted': return `${c.cyan}${status}${c.reset}`;
30
+ case 'completed': return `${c.green}${status}${c.reset}`;
31
+ case 'rejected': return `${c.red}${status}${c.reset}`;
32
+ case 'expired': return `${c.gray}${status}${c.reset}`;
33
+ case 'negotiating': return `${c.magenta}${status}${c.reset}`;
34
+ case 'accepted': return `${c.green}${status}${c.reset}`;
35
+ case 'cancelled': return `${c.gray}${status}${c.reset}`;
36
+ default: return status;
37
+ }
38
+ }
39
+ export function parseRelativeTime(input) {
40
+ const match = input.match(/^(\d+)\s*(h|hr|hrs|hour|hours|d|day|days|m|min|mins|minute|minutes)$/i);
41
+ if (!match) {
42
+ const d = new Date(input);
43
+ if (!isNaN(d.getTime()))
44
+ return d.toISOString();
45
+ throw new Error(`Cannot parse expiry: "${input}". Use formats like "24h", "7d".`);
46
+ }
47
+ const num = parseInt(match[1], 10);
48
+ const unit = match[2].toLowerCase();
49
+ const ms = unit.startsWith('h') ? num * 3600e3 : unit.startsWith('d') ? num * 86400e3 : num * 60e3;
50
+ return new Date(Date.now() + ms).toISOString();
51
+ }
52
+ export function parseTimeToSeconds(input) {
53
+ const match = input.match(/^(\d+)\s*(s|sec|secs|second|seconds|h|hr|hrs|hour|hours|d|day|days|m|min|mins|minute|minutes)$/i);
54
+ if (!match)
55
+ throw new Error(`Cannot parse time: "${input}". Use formats like "48h", "7d".`);
56
+ const n = parseInt(match[1], 10);
57
+ const u = match[2].toLowerCase();
58
+ if (u.startsWith('s'))
59
+ return n;
60
+ if (u.startsWith('m'))
61
+ return n * 60;
62
+ if (u.startsWith('h'))
63
+ return n * 3600;
64
+ if (u.startsWith('d'))
65
+ return n * 86400;
66
+ return n;
67
+ }
68
+ //# sourceMappingURL=display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"display.js","sourceRoot":"","sources":["../../src/runtime/display.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Typed errors with stable exit codes. Shared by CLI and MCP adapter.
3
+ *
4
+ * Exit codes:
5
+ * 1 = user error (bad input, missing flag)
6
+ * 2 = network error (fetch failed, non-2xx from API)
7
+ * 3 = payment / signing error (wallet missing, 402 retry failed)
8
+ * 4 = on-chain error (revert, unknown event)
9
+ */
10
+ export type ExitCode = 1 | 2 | 3 | 4;
11
+ export declare class CliError extends Error {
12
+ readonly code: ExitCode;
13
+ readonly details?: Record<string, unknown>;
14
+ constructor(message: string, code: ExitCode, details?: Record<string, unknown>);
15
+ }
16
+ export declare const userError: (msg: string, details?: Record<string, unknown>) => CliError;
17
+ export declare const networkError: (msg: string, details?: Record<string, unknown>) => CliError;
18
+ export declare const paymentError: (msg: string, details?: Record<string, unknown>) => CliError;
19
+ export declare const chainError: (msg: string, details?: Record<string, unknown>) => CliError;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Typed errors with stable exit codes. Shared by CLI and MCP adapter.
3
+ *
4
+ * Exit codes:
5
+ * 1 = user error (bad input, missing flag)
6
+ * 2 = network error (fetch failed, non-2xx from API)
7
+ * 3 = payment / signing error (wallet missing, 402 retry failed)
8
+ * 4 = on-chain error (revert, unknown event)
9
+ */
10
+ export class CliError extends Error {
11
+ code;
12
+ details;
13
+ constructor(message, code, details) {
14
+ super(message);
15
+ this.code = code;
16
+ this.details = details;
17
+ }
18
+ }
19
+ export const userError = (msg, details) => new CliError(msg, 1, details);
20
+ export const networkError = (msg, details) => new CliError(msg, 2, details);
21
+ export const paymentError = (msg, details) => new CliError(msg, 3, details);
22
+ export const chainError = (msg, details) => new CliError(msg, 4, details);
23
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/runtime/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAW;IACf,OAAO,CAA2B;IAC3C,YAAY,OAAe,EAAE,IAAc,EAAE,OAAiC;QAC5E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAED,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAW,EAAE,OAAiC,EAAE,EAAE,CAC1E,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AAChC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,OAAiC,EAAE,EAAE,CAC7E,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AAChC,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAW,EAAE,OAAiC,EAAE,EAAE,CAC7E,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AAChC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,OAAiC,EAAE,EAAE,CAC3E,IAAI,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * HTTP client for Obolos backend. Throws `networkError` on non-2xx.
3
+ * Does NOT handle x402 — payment flow lives in runtime/payment.ts.
4
+ */
5
+ export interface HttpClient {
6
+ get<T = unknown>(path: string): Promise<T>;
7
+ post<T = unknown>(path: string, body?: unknown, headers?: Record<string, string>): Promise<T>;
8
+ }
9
+ export declare function createHttpClient(baseUrl: string): HttpClient;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * HTTP client for Obolos backend. Throws `networkError` on non-2xx.
3
+ * Does NOT handle x402 — payment flow lives in runtime/payment.ts.
4
+ */
5
+ import { networkError } from './errors.js';
6
+ export function createHttpClient(baseUrl) {
7
+ async function parseOrThrow(res) {
8
+ if (res.ok)
9
+ return res.json();
10
+ let msg = `${res.status} ${res.statusText}`;
11
+ try {
12
+ const err = await res.json();
13
+ if (err?.error)
14
+ msg = err.error;
15
+ else if (err?.message)
16
+ msg = err.message;
17
+ }
18
+ catch { }
19
+ throw networkError(msg, { status: res.status, url: res.url });
20
+ }
21
+ return {
22
+ async get(path) {
23
+ const res = await fetch(`${baseUrl}${path}`);
24
+ return parseOrThrow(res);
25
+ },
26
+ async post(path, body, headers) {
27
+ const res = await fetch(`${baseUrl}${path}`, {
28
+ method: 'POST',
29
+ headers: { 'Content-Type': 'application/json', ...(headers ?? {}) },
30
+ body: body !== undefined ? JSON.stringify(body) : undefined,
31
+ });
32
+ return parseOrThrow(res);
33
+ },
34
+ };
35
+ }
36
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/runtime/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,KAAK,UAAU,YAAY,CAAC,GAAa;QACvC,IAAI,GAAG,CAAC,EAAE;YAAE,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,EAAE,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,GAAG,EAAE,KAAK;gBAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC;iBAC3B,IAAI,GAAG,EAAE,OAAO;gBAAE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC;QAC3C,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;QACV,MAAM,YAAY,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,OAAO;QACL,KAAK,CAAC,GAAG,CAAC,IAAI;YACZ,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,CAAC,CAAC;YAC7C,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO;YAC5B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,GAAG,IAAI,EAAE,EAAE;gBAC3C,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE;gBACnE,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;aAC5D,CAAC,CAAC;YACH,OAAO,YAAY,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * RunContext is passed to every Command.run(). Commands MUST NOT write to
3
+ * stdout/stderr directly — return structured output from run(), and the
4
+ * runtime picks pretty (format()) or JSON rendering based on ctx.json.
5
+ *
6
+ * This invariant is what lets the same command serve both a human in a
7
+ * terminal and an MCP client that needs a stable JSON envelope.
8
+ */
9
+ import type { HttpClient } from './http.js';
10
+ import type { ObolosConfig } from './config.js';
11
+ export type OutputMode = 'pretty' | 'json';
12
+ export interface RunContext {
13
+ config: ObolosConfig;
14
+ http: HttpClient;
15
+ source: 'cli' | 'mcp';
16
+ json: boolean;
17
+ dryRun: boolean;
18
+ }
19
+ export declare function renderJson(output: unknown): string;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * RunContext is passed to every Command.run(). Commands MUST NOT write to
3
+ * stdout/stderr directly — return structured output from run(), and the
4
+ * runtime picks pretty (format()) or JSON rendering based on ctx.json.
5
+ *
6
+ * This invariant is what lets the same command serve both a human in a
7
+ * terminal and an MCP client that needs a stable JSON envelope.
8
+ */
9
+ export function renderJson(output) {
10
+ return JSON.stringify(output, (_, v) => (typeof v === 'bigint' ? v.toString() : v), 2);
11
+ }
12
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/runtime/output.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH,MAAM,UAAU,UAAU,CAAC,MAAe;IACxC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACzF,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * x402 payment handling — sign EIP-3009 TransferWithAuthorization for a
3
+ * 402 challenge and retry the original request. Supports v1 "exact" scheme
4
+ * and v2 "x402x-router-settlement" (atomic fee split).
5
+ *
6
+ * Extracted from cmdCall so the CLI `call` command and any MCP adapter
7
+ * share the same flow.
8
+ */
9
+ import type { ObolosConfig } from './config.js';
10
+ export interface CallOptions {
11
+ method?: string;
12
+ body?: unknown;
13
+ }
14
+ export interface CallResult {
15
+ status: number;
16
+ statusText: string;
17
+ contentType: string;
18
+ body: unknown;
19
+ paid: boolean;
20
+ }
21
+ export declare function callWithPayment(config: ObolosConfig, apiId: string, opts?: CallOptions): Promise<CallResult>;