@jecpdev/cli 0.1.0 → 0.3.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.
package/dist/cli.js CHANGED
@@ -23,8 +23,8 @@ program.command("logout").description("Clear stored credentials").action(async (
23
23
  const { logoutCmd } = await import("./login-2C7JY62W.js");
24
24
  await logoutCmd();
25
25
  });
26
- program.command("invoke <capability> <action>").description("Invoke a capability action (capability format: namespace/capability)").option("-i, --input <json>", "Input as JSON string", "{}").option("-b, --budget <usdc>", "Mandate budget cap in USDC (e.g. 1.00)").option("-t, --timeout <ms>", "Request timeout in milliseconds").option("--request-id <id>", "Override idempotency key (default: auto UUID)").action(async (capability, action, opts) => {
27
- const { invokeCmd } = await import("./invoke-NHTPS6NN.js");
26
+ program.command("invoke <capability> <action>").description("Invoke a capability action (capability format: namespace/capability)").option("-i, --input <json>", "Input as JSON string", "{}").option("-b, --budget <usdc>", "Mandate budget cap in USDC (e.g. 1.00)").option("-t, --timeout <ms>", "Request timeout in milliseconds").option("--request-id <id>", "Override idempotency key (default: auto UUID)").option("--stream", "Stream the response as Server-Sent Events. Capability action must declare streaming: true.").action(async (capability, action, opts) => {
27
+ const { invokeCmd } = await import("./invoke-NILLA4U4.js");
28
28
  await invokeCmd(capability, action, opts);
29
29
  });
30
30
  program.command("catalog").description("List capabilities (paginated by default)").option("--page-size <n>", "Items per page (1-200)", "50").option("--namespace <ns>", "Filter by Provider namespace").option("--tags <csv>", "Comma-separated tag filter").option("--all", "Fetch all in legacy mode (?paginated=false)").action(async (opts) => {
@@ -43,6 +43,32 @@ program.command("doctor").description("Diagnose connectivity, config, and SDK ve
43
43
  const { doctorCmd } = await import("./doctor-7Y7WBLQZ.js");
44
44
  await doctorCmd();
45
45
  });
46
+ var refund = program.command("refund").description("Refund management (W2)");
47
+ refund.command("request <transaction_id>").description("Request a refund within 30 days of the original charge").requiredOption("--reason <text>", "Reason (max 500 chars)").option("--evidence-url <url>", "Optional URL to evidence (screenshot, log)").action(async (txId, opts) => {
48
+ const { refundRequestCmd } = await import("./refund-OZY2WZVG.js");
49
+ await refundRequestCmd(txId, opts);
50
+ });
51
+ refund.command("get <refund_id>").description("Read a refund by id").action(async (refundId) => {
52
+ const { refundGetCmd } = await import("./refund-OZY2WZVG.js");
53
+ await refundGetCmd(refundId);
54
+ });
55
+ refund.command("list").description("List your refunds").option("--limit <n>", "Max items (1-200)", "50").action(async (opts) => {
56
+ const { refundListCmd } = await import("./refund-OZY2WZVG.js");
57
+ await refundListCmd(opts);
58
+ });
59
+ var webhook = program.command("webhook").description("Webhook subscription management (W4)");
60
+ webhook.command("subscribe").description("Subscribe to webhook events. Returns hmac_secret (one-time)").requiredOption("--url <url>", "Endpoint URL (must be https://)").option("--events <csv>", "Comma-separated event types (omit for all)").action(async (opts) => {
61
+ const { webhookSubscribeCmd } = await import("./webhook-3O6CGNJ3.js");
62
+ await webhookSubscribeCmd(opts);
63
+ });
64
+ webhook.command("list").description("List your webhook subscriptions").action(async () => {
65
+ const { webhookListCmd } = await import("./webhook-3O6CGNJ3.js");
66
+ await webhookListCmd();
67
+ });
68
+ webhook.command("test <subscription_id>").description("Send a synthetic test event to your endpoint").action(async (subId) => {
69
+ const { webhookTestCmd } = await import("./webhook-3O6CGNJ3.js");
70
+ await webhookTestCmd(subId);
71
+ });
46
72
  program.parseAsync(process.argv).catch((e) => {
47
73
  fail(e.message);
48
74
  });
@@ -37,6 +37,10 @@ async function invokeCmd(capability, action, opts) {
37
37
  if (opts.requestId !== void 0) {
38
38
  invokeOpts.requestId = opts.requestId;
39
39
  }
40
+ if (opts.stream) {
41
+ await runStream(jecp, capability, action, input, invokeOpts);
42
+ return;
43
+ }
40
44
  try {
41
45
  const r = await jecp.invoke(capability, action, input, invokeOpts);
42
46
  emit(
@@ -87,6 +91,60 @@ async function invokeCmd(capability, action, opts) {
87
91
  throw e;
88
92
  }
89
93
  }
94
+ async function runStream(jecp, capability, action, input, invokeOpts) {
95
+ const stream = jecp.invokeStream(capability, action, input, invokeOpts);
96
+ let exitCode = 0;
97
+ try {
98
+ for await (const event of stream) {
99
+ switch (event.type) {
100
+ case "chunk":
101
+ process.stdout.write(event.delta);
102
+ break;
103
+ case "meter":
104
+ if (event.tokens !== void 0) {
105
+ process.stderr.write(dim(`
106
+ [meter] tokens=${event.tokens}
107
+ `));
108
+ }
109
+ break;
110
+ case "completed":
111
+ process.stdout.write("\n");
112
+ success("Stream completed.");
113
+ info(`${bold("Billing:")} ${event.billing && event.billing.charged ? `$${event.billing.amount_usdc} USDC (tx ${event.billing.transaction_id ?? "\u2014"})` : "not charged"}`);
114
+ break;
115
+ case "error": {
116
+ process.stdout.write("\n");
117
+ error(`${event.error.code}: ${event.error.message}`);
118
+ exitCode = 1;
119
+ break;
120
+ }
121
+ case "cancelled":
122
+ process.stdout.write("\n");
123
+ warn(`Cancelled${event.reason ? `: ${event.reason}` : ""}`);
124
+ if (event.billing && event.billing.charged) {
125
+ info(`Partial bill: $${event.billing.amount_usdc} USDC`);
126
+ }
127
+ exitCode = 1;
128
+ break;
129
+ }
130
+ }
131
+ } catch (e) {
132
+ if (e instanceof JecpError) {
133
+ error(`${e.code}: ${e.message}`);
134
+ if (e.nextAction) {
135
+ info("");
136
+ info(bold("Next action:"));
137
+ info(` type: ${e.nextAction.type}`);
138
+ if ("hint" in e.nextAction && e.nextAction.hint) {
139
+ info(` hint: ${e.nextAction.hint}`);
140
+ }
141
+ }
142
+ process.exit(1);
143
+ }
144
+ throw e;
145
+ }
146
+ if (exitCode !== 0) process.exit(exitCode);
147
+ }
90
148
  export {
91
149
  invokeCmd
92
150
  };
@@ -0,0 +1,59 @@
1
+ import {
2
+ getClient
3
+ } from "./chunk-FH4G7W5M.js";
4
+ import {
5
+ bold,
6
+ dim,
7
+ emit,
8
+ fail,
9
+ info,
10
+ success
11
+ } from "./chunk-AHQEKKK7.js";
12
+ import "./chunk-DZLDBWTB.js";
13
+
14
+ // src/commands/refund.ts
15
+ async function refundRequestCmd(transactionId, opts) {
16
+ if (!opts.reason) fail("--reason required");
17
+ const jecp = getClient();
18
+ const r = await jecp.requestRefund({
19
+ transaction_id: transactionId,
20
+ reason: opts.reason,
21
+ ...opts.evidenceUrl && { evidence_url: opts.evidenceUrl }
22
+ });
23
+ emit(r, () => {
24
+ success("Refund requested.");
25
+ info("");
26
+ info(`${bold("Refund ID:")} ${r.refund_id}`);
27
+ info(`${bold("Status:")} ${r.status}`);
28
+ info(`${bold("Amount:")} $${r.amount_usdc} USDC`);
29
+ if (r.estimated_resolution) {
30
+ info(`${dim(`Auto-resolves: ${r.estimated_resolution}`)}`);
31
+ }
32
+ });
33
+ }
34
+ async function refundGetCmd(refundId) {
35
+ const jecp = getClient();
36
+ const r = await jecp.getRefund(refundId);
37
+ emit(r);
38
+ }
39
+ async function refundListCmd(opts) {
40
+ const jecp = getClient();
41
+ const limit = opts.limit ? parseInt(opts.limit, 10) : 50;
42
+ const r = await jecp.listRefunds({ limit });
43
+ emit(r, () => {
44
+ info(bold(`Refunds (${r.count}):`));
45
+ info("");
46
+ for (const item of r.refunds) {
47
+ const s = item.status === "requested" ? "\u22EF" : item.status === "denied" ? "\u2717" : "\u2713";
48
+ info(` ${s} ${bold(item.refund_id)} $${item.amount_usdc} [${item.status}]`);
49
+ info(` ${dim(item.reason)}`);
50
+ info(` ${dim("requested " + item.requested_at)}`);
51
+ info("");
52
+ }
53
+ });
54
+ }
55
+ export {
56
+ refundGetCmd,
57
+ refundListCmd,
58
+ refundRequestCmd
59
+ };
@@ -0,0 +1,65 @@
1
+ import {
2
+ getClient
3
+ } from "./chunk-FH4G7W5M.js";
4
+ import {
5
+ bold,
6
+ dim,
7
+ emit,
8
+ info,
9
+ success
10
+ } from "./chunk-AHQEKKK7.js";
11
+ import "./chunk-DZLDBWTB.js";
12
+
13
+ // src/commands/webhook.ts
14
+ async function webhookSubscribeCmd(opts) {
15
+ const jecp = getClient();
16
+ const events = opts.events ? opts.events.split(",").map((e) => e.trim()).filter(Boolean) : void 0;
17
+ const sub = await jecp.subscribe({
18
+ endpoint_url: opts.url,
19
+ ...events && { events }
20
+ });
21
+ emit(sub, () => {
22
+ success("Subscription created.");
23
+ info("");
24
+ info(`${bold("Subscription ID:")} ${sub.subscription_id}`);
25
+ info(`${bold("Endpoint:")} ${sub.endpoint_url}`);
26
+ info(`${bold("Events:")} ${sub.events.length === 0 ? "all" : sub.events.join(", ")}`);
27
+ info("");
28
+ info(bold("HMAC SECRET (shown once \u2014 save it now):"));
29
+ info(` ${sub.hmac_secret}`);
30
+ info("");
31
+ info(dim("Use this secret with @jecpdev/sdk verifyWebhook() to validate inbound events."));
32
+ });
33
+ }
34
+ async function webhookListCmd() {
35
+ const jecp = getClient();
36
+ const r = await jecp.listSubscriptions();
37
+ emit(r, () => {
38
+ info(bold(`Webhook subscriptions (${r.count}):`));
39
+ info("");
40
+ for (const s of r.subscriptions) {
41
+ const mark = s.status === "active" ? "\u25CF" : "\u25CB";
42
+ info(` ${mark} ${bold(s.subscription_id)} [${s.status}]`);
43
+ info(` ${s.endpoint_url}`);
44
+ info(` ${dim("events: " + (s.events.length === 0 ? "all" : s.events.join(", ")))}`);
45
+ if (s.failures_consecutive > 0) {
46
+ info(` ${dim("\u26A0 " + s.failures_consecutive + " consecutive failures")}`);
47
+ }
48
+ info("");
49
+ }
50
+ });
51
+ }
52
+ async function webhookTestCmd(subscriptionId) {
53
+ const jecp = getClient();
54
+ const r = await jecp.testSubscription(subscriptionId);
55
+ emit(r, () => {
56
+ success("Test event enqueued.");
57
+ info(`${bold("Event ID:")} ${r.event_id}`);
58
+ info(dim("Check your endpoint logs \u2014 delivery within ~2-5 seconds."));
59
+ });
60
+ }
61
+ export {
62
+ webhookListCmd,
63
+ webhookSubscribeCmd,
64
+ webhookTestCmd
65
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jecpdev/cli",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "Command-line interface for JECP — register agents, invoke capabilities, manage Providers from your terminal.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,7 +8,11 @@
8
8
  },
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
11
- "files": ["dist", "README.md", "LICENSE"],
11
+ "files": [
12
+ "dist",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
12
16
  "engines": {
13
17
  "node": ">=20"
14
18
  },
@@ -39,7 +43,7 @@
39
43
  "access": "public"
40
44
  },
41
45
  "dependencies": {
42
- "@jecpdev/sdk": "^0.2.0",
46
+ "@jecpdev/sdk": "^0.4.0",
43
47
  "commander": "^13.0.0",
44
48
  "kleur": "^4.1.5",
45
49
  "prompts": "^2.4.2"