@jecpdev/cli 0.2.0 → 0.4.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,10 @@ 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
+ program.command("rotate-key").description("Rotate this agent's API key. Previous key remains valid for 7 days.").option("--grace-seconds <int>", "Override grace window in seconds (60..604800)").option("--yes", "Skip the interactive confirmation").action(async (opts) => {
47
+ const { rotateKeyCmd } = await import("./rotate-key-KBM2WSR7.js");
48
+ await rotateKeyCmd(opts);
49
+ });
46
50
  var refund = program.command("refund").description("Refund management (W2)");
47
51
  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
52
  const { refundRequestCmd } = await import("./refund-OZY2WZVG.js");
@@ -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,82 @@
1
+ import {
2
+ getClient
3
+ } from "./chunk-FH4G7W5M.js";
4
+ import {
5
+ bold,
6
+ dim,
7
+ emit,
8
+ error,
9
+ info,
10
+ success,
11
+ warn
12
+ } from "./chunk-AHQEKKK7.js";
13
+ import {
14
+ configFilePath,
15
+ loadConfig,
16
+ saveConfig
17
+ } from "./chunk-DZLDBWTB.js";
18
+
19
+ // src/commands/rotate-key.ts
20
+ import prompts from "prompts";
21
+ import { JecpError } from "@jecpdev/sdk";
22
+ async function rotateKeyCmd(opts) {
23
+ if (!opts.yes) {
24
+ const ans = await prompts({
25
+ type: "confirm",
26
+ name: "go",
27
+ message: "Rotate this agent's API key? The previous key remains valid for 7 days unless overridden.",
28
+ initial: false
29
+ });
30
+ if (!ans.go) {
31
+ info("Aborted.");
32
+ return;
33
+ }
34
+ }
35
+ const grace = opts.graceSeconds !== void 0 ? parseInt(opts.graceSeconds, 10) : void 0;
36
+ if (grace !== void 0 && (Number.isNaN(grace) || grace < 60 || grace > 604800)) {
37
+ error("--grace-seconds must be an integer between 60 and 604800 (7 days).");
38
+ process.exit(1);
39
+ }
40
+ const jecp = getClient();
41
+ try {
42
+ const r = await jecp.rotateApiKey(grace !== void 0 ? { graceSeconds: grace } : {});
43
+ const cfg = loadConfig();
44
+ if (cfg.agent_id && cfg.agent_id === r.agent_id) {
45
+ cfg.api_key = r.api_key;
46
+ saveConfig(cfg);
47
+ }
48
+ emit(
49
+ {
50
+ agent_id: r.agent_id,
51
+ api_key: r.api_key,
52
+ previous_key_valid_until: r.previous_key_valid_until,
53
+ grace_seconds: r.grace_seconds,
54
+ config_file: configFilePath()
55
+ },
56
+ () => {
57
+ success("Agent API key rotated.");
58
+ info("");
59
+ info(`${bold("New api_key:")} ${r.api_key}`);
60
+ info(`${bold("Previous key valid until:")} ${r.previous_key_valid_until}`);
61
+ info(`${bold("Grace seconds:")} ${r.grace_seconds}`);
62
+ info("");
63
+ if (cfg.agent_id === r.agent_id) {
64
+ info(dim(`Saved to ${configFilePath()} (chmod 600).`));
65
+ } else {
66
+ warn("Local config did not match this agent \u2014 new key NOT auto-saved.");
67
+ }
68
+ info("");
69
+ warn("This api_key is shown only once. Persist it now in your secret store.");
70
+ }
71
+ );
72
+ } catch (e) {
73
+ if (e instanceof JecpError) {
74
+ error(`${e.code}: ${e.message}`);
75
+ process.exit(1);
76
+ }
77
+ throw e;
78
+ }
79
+ }
80
+ export {
81
+ rotateKeyCmd
82
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jecpdev/cli",
3
- "version": "0.2.0",
3
+ "version": "0.4.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": {
@@ -43,7 +43,7 @@
43
43
  "access": "public"
44
44
  },
45
45
  "dependencies": {
46
- "@jecpdev/sdk": "^0.3.0",
46
+ "@jecpdev/sdk": "^0.5.0",
47
47
  "commander": "^13.0.0",
48
48
  "kleur": "^4.1.5",
49
49
  "prompts": "^2.4.2"