@certen.io/cli 0.3.1 → 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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,88 @@
1
+ # Changelog — @certen.io/cli
2
+
3
+ ## 0.5.0 — money commands, and a refusal that tells you how to fix it
4
+
5
+ ### Added — `certen balance` and `certen fund`
6
+
7
+ `balance` prints available, held, credit line, spendable, and **left to commit** — spendable minus
8
+ what pending intents have already claimed. Showing only the balance would tell you that you can
9
+ afford work that is already spoken for.
10
+
11
+ `fund <amount> --chain <chain>` prints where to send stablecoin and waits until it is credited.
12
+ It never touches a wallet or a key: signing and sending stay with you. `--no-wait` prints the
13
+ details and exits; `--poll-interval` and `--timeout` control the wait. An uncredited or expired
14
+ payment exits non-zero, because a funding script must not read one as paid.
15
+
16
+ Every option is validated before the network call — a typo in `--timeout` used to open a real
17
+ payment intent first.
18
+
19
+ ### Changed — a 402 now prints the way out
20
+
21
+ A refusal for lack of funds shows the shortfall, the address, the exact amount, the reference, both
22
+ `certen fund …` and the portal link, and the quote id to retry with — then states plainly that
23
+ nothing was charged and no work was started. All on stderr; stdout is untouched.
24
+
25
+ In `--json`, the failure envelope gains `shortfall_usd`, `quote_id` and `resolve` on payment
26
+ failures only. They are absent on every other error rather than present as nulls. See
27
+ docs/CLI-CONTRACT.md.
28
+
29
+ ### Fixed — the error reporter no longer flattens SDK errors
30
+
31
+ `handleError` copied a `CertenError` into an object literal before reporting it. The values
32
+ survived; the class identity did not — so a payment refusal could not be recognised and its payment
33
+ target was silently dropped. The fields it copied are all readable on the instance, `isRetryable`
34
+ getter included, so nothing was gained by the copy.
35
+
36
+ ## 0.4.0 — `--json` is a machine contract
37
+
38
+ Adds a stable, tested output contract for scripts and AI agents. **Human output is unchanged**: if
39
+ you do not pass `--json`, this release behaves exactly as 0.3.1 did, with one exception noted under
40
+ Breaking.
41
+
42
+ Before this, every failure exited `1` and explained itself in English on stderr. An automated caller
43
+ could not distinguish "you passed a malformed address" from "the gateway is down" without parsing
44
+ prose — and those want opposite responses. One is a bug to fix; the other is worth retrying. For a
45
+ CLI that authorizes cross-chain execution against real funds, guessing wrong is expensive in a way
46
+ that is not recoverable.
47
+
48
+ The full specification is [docs/CLI-CONTRACT.md](../../docs/CLI-CONTRACT.md), enforced by
49
+ `test/conformance.test.ts`, which runs the built binary as a subprocess and checks the real process's
50
+ stdout and exit code.
51
+
52
+ ### Added
53
+
54
+ - **Global `--json`**, accepted anywhere in the argument list — `certen --json tx status X` and
55
+ `certen tx status X --json` are identical. It is resolved before argument parsing, so it applies
56
+ even to failures that occur while resolving credentials.
57
+ - **One JSON envelope on stdout and nothing else.** `{"ok":true,"data":…}` or
58
+ `{"ok":false,"error":{"code","message","retryable","status?","requestId?"}}`. A command producing
59
+ several payloads emits an array in `data`; one producing none emits `"data":null`. stdout is never
60
+ empty and never carries two concatenated objects. All human-facing text moves to stderr.
61
+ - **Meaningful exit codes:** `0` ok · `1` operation failed · `2` usage error · `3` gateway
62
+ unreachable. `3` guarantees nothing was submitted, so a retry cannot double-execute.
63
+ - **`error.retryable`**, taken from the SDK's own `CertenError.isRetryable`, so the CLI and the SDK
64
+ hand an automated caller the identical retry decision.
65
+ - **`certen --help --json`** returns the entire command tree — every command, argument, flag and exit
66
+ code — in one call, instead of scraping help text once per subcommand.
67
+
68
+ ### Fixed
69
+
70
+ - **Usage errors on subcommands bypassed error handling entirely.** `exitOverride()` is not inherited
71
+ by commander subcommands, so a missing required flag (`certen identity create` with no `--name`)
72
+ called `process.exit(1)` inside commander: no envelope was emitted, stdout stayed empty, and a
73
+ usage error was indistinguishable from a failed request. It is now applied to every command in the
74
+ tree.
75
+
76
+ ### Breaking
77
+
78
+ - **"No API key configured" now exits `2` instead of `1`.** It is a usage error: nothing was sent,
79
+ and retrying cannot help. The same applies to a config file with unsafe permissions and to a
80
+ missing keyring backend. Scripts treating any non-zero exit as failure are unaffected; scripts
81
+ testing specifically for `-eq 1` need updating.
82
+
83
+ ### Note
84
+
85
+ `output: "json"` in `~/.certen/config.json` is **not** this contract. That setting predates the
86
+ envelope and makes commands print their raw payload — no `ok`, no `error`, no exit-code guarantees.
87
+ It is kept for backward compatibility. Automated callers should pass `--json` explicitly rather than
88
+ depend on a machine's local config, which they cannot see.
package/README.md CHANGED
@@ -97,6 +97,30 @@ certen admin audit-log | usage
97
97
 
98
98
  Run `certen <group> --help` for the flags on any of them.
99
99
 
100
+ ## Scripting and AI agents: `--json`
101
+
102
+ `--json` turns the CLI into a machine interface. It is a contract, documented in full in
103
+ [docs/CLI-CONTRACT.md](../../docs/CLI-CONTRACT.md) and enforced by a conformance suite.
104
+
105
+ ```bash
106
+ certen --json tx status <id>
107
+ # {"ok":true,"data":{"intent_id":"…","status":"completed"}}
108
+
109
+ certen --json portfolio
110
+ # {"ok":false,"error":{"code":"NETWORK_ERROR","message":"connect ECONNREFUSED","retryable":true,"status":0}}
111
+ ```
112
+
113
+ - **Exactly one JSON object on stdout**, nothing else. Every human-facing line goes to stderr.
114
+ - **Exit codes:** `0` ok · `1` operation failed · `2` usage error · `3` gateway unreachable. Branch on
115
+ these instead of parsing text. `3` guarantees nothing was submitted, so a retry cannot
116
+ double-execute.
117
+ - **`error.retryable`** comes from the SDK's own `CertenError.isRetryable`, so the CLI and the SDK
118
+ give an identical retry decision.
119
+ - **`certen --help --json`** returns the entire command tree — every command, flag and exit code — in
120
+ one call.
121
+
122
+ Without `--json`, output is the human table format as before. Do not parse it.
123
+
100
124
  ## Configuration
101
125
 
102
126
  | | |
@@ -1,5 +1,5 @@
1
1
  import { readConfig, writeConfig, setApiKey, clearApiKey, DEFAULT_API_URL } from '../config.js';
2
- import { printOutput } from '../output.js';
2
+ import { printOutput, human } from '../output.js';
3
3
  export function registerAuthCommands(program) {
4
4
  const auth = program.command('auth').description('Authentication management');
5
5
  auth
@@ -23,14 +23,14 @@ export function registerAuthCommands(program) {
23
23
  cfg.api_url = opts.apiUrl;
24
24
  writeConfig(cfg);
25
25
  }
26
- console.log(useKeyring ? 'API key saved to OS keyring' : 'API key saved to ~/.certen/config.json (mode 0600)');
26
+ human(useKeyring ? 'API key saved to OS keyring' : 'API key saved to ~/.certen/config.json (mode 0600)');
27
27
  });
28
28
  auth
29
29
  .command('logout')
30
30
  .description('Remove the saved API key from keyring or config file')
31
31
  .action(async () => {
32
32
  await clearApiKey();
33
- console.log('API key cleared');
33
+ human('API key cleared');
34
34
  });
35
35
  auth
36
36
  .command('status')
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerBillingCommands(program: Command): void;
@@ -0,0 +1,174 @@
1
+ import { CertenClient } from '@certen.io/sdk';
2
+ import { getApiKey, getApiUrl } from '../config.js';
3
+ import { printOutput, human, hint, isJsonMode } from '../output.js';
4
+ import { CliError, EXIT } from '../errors.js';
5
+ /**
6
+ * Money commands.
7
+ *
8
+ * These exist because the gateway enforces payment on every execution path while
9
+ * no client surface could add funds — so usage accrued against a credit line with
10
+ * no way to settle it. A developer refused for lack of funds needs the fix in the
11
+ * terminal they were already in, not a link to go and read.
12
+ *
13
+ * `fund` never touches a wallet or a private key. It asks the gateway where to
14
+ * send stablecoin, prints that, and waits. Signing and sending stay entirely with
15
+ * the customer's own wallet.
16
+ */
17
+ async function getClient() {
18
+ return new CertenClient({ apiKey: await getApiKey(), baseUrl: getApiUrl() });
19
+ }
20
+ /** "12.340000" -> "$12.34". Trims the string; never parses money into a float. */
21
+ function usd(amount) {
22
+ const [whole, frac = ''] = String(amount).split('.');
23
+ const neg = whole.startsWith('-');
24
+ return `${neg ? '-$' : '$'}${neg ? whole.slice(1) : whole}.${(frac + '00').slice(0, 2)}`;
25
+ }
26
+ function minutesUntil(iso) {
27
+ return Math.max(0, Math.round((new Date(iso).getTime() - Date.now()) / 60_000));
28
+ }
29
+ export function registerBillingCommands(program) {
30
+ program
31
+ .command('balance')
32
+ .description('Show your balance and what pending work has already claimed')
33
+ .action(async () => {
34
+ const client = await getClient();
35
+ // Both, because either alone misleads: the balance looks healthy while
36
+ // every cent of it is committed to intents awaiting quorum.
37
+ const [balance, obligations] = await Promise.all([
38
+ client.billing.balance(),
39
+ client.billing.obligations(),
40
+ ]);
41
+ printOutput({
42
+ currency: balance.currency,
43
+ available_usd: balance.available_usd,
44
+ held_usd: balance.held_usd,
45
+ credit_limit_usd: balance.credit_limit_usd,
46
+ spendable_usd: balance.spendable_usd,
47
+ remaining_usd: obligations.remaining_usd,
48
+ pending_intents: obligations.pending_intents,
49
+ uncovered_usd: obligations.uncovered_usd,
50
+ status: balance.status,
51
+ });
52
+ if (isJsonMode())
53
+ return;
54
+ human('');
55
+ human(` Available ${usd(balance.available_usd)}`);
56
+ human(` Held for in-flight ${usd(balance.held_usd)}`);
57
+ if (balance.credit_limit_usd !== '0.000000') {
58
+ human(` Credit line ${usd(balance.credit_limit_usd)}`);
59
+ }
60
+ human(` Spendable ${usd(balance.spendable_usd)}`);
61
+ human(` Left to commit ${usd(obligations.remaining_usd)}`);
62
+ human('');
63
+ if (obligations.pending_intents > 0) {
64
+ human(` ${obligations.pending_intents} pending intent(s) have claimed `
65
+ + `${usd(obligations.uncovered_usd)} of that.`);
66
+ }
67
+ if (Number(obligations.remaining_usd) <= 0) {
68
+ human(' You cannot start new work until you add funds.');
69
+ hint('certen fund <amount> --chain <chain>');
70
+ }
71
+ if (balance.status !== 'active') {
72
+ human(` Account status: ${balance.status}.`);
73
+ }
74
+ });
75
+ program
76
+ .command('fund')
77
+ .argument('<amount>', 'Amount in USD to send, e.g. 25 or 25.50')
78
+ .description('Get payment details for adding funds, and wait until they are credited')
79
+ .option('--chain <chain>', 'Chain to send stablecoin on (e.g. base)')
80
+ .option('--no-wait', 'Print the payment details and exit instead of waiting')
81
+ .option('--timeout <minutes>', 'How long to wait for the deposit', '60')
82
+ // Scripted callers legitimately want a different cadence — a CI job funding a
83
+ // test account should not sit on a 5-second loop, and a long unattended wait
84
+ // should poll gently. Exposed rather than hard-coded.
85
+ .option('--poll-interval <seconds>', 'How often to check for the deposit', '5')
86
+ .action(async (amount, opts) => {
87
+ if (!/^\d+(\.\d{1,6})?$/.test(amount) || Number(amount) <= 0) {
88
+ throw new CliError(`"${amount}" is not a valid amount. Use a number of dollars, e.g. 25 or 25.50`, 'INVALID_AMOUNT', EXIT.USAGE);
89
+ }
90
+ if (!opts.chain) {
91
+ throw new CliError('Which chain will you send on? Pass --chain (e.g. --chain base)', 'CHAIN_REQUIRED', EXIT.USAGE);
92
+ }
93
+ // Every option is validated BEFORE the network call. Checking after would
94
+ // mean a typo in --timeout had already opened a real payment intent that the
95
+ // customer then has to wait out or abandon.
96
+ const timeoutMin = Number(opts.timeout);
97
+ if (!Number.isFinite(timeoutMin) || timeoutMin <= 0) {
98
+ throw new CliError('--timeout must be a positive number of minutes', 'INVALID_TIMEOUT', EXIT.USAGE);
99
+ }
100
+ const pollSec = Number(opts.pollInterval);
101
+ if (!Number.isFinite(pollSec) || pollSec <= 0) {
102
+ throw new CliError('--poll-interval must be a positive number of seconds', 'INVALID_POLL_INTERVAL', EXIT.USAGE);
103
+ }
104
+ const client = await getClient();
105
+ const target = await client.billing.openPayment({ chain: opts.chain, amountUsd: amount });
106
+ const intent = target.deposit_intent;
107
+ if (!intent) {
108
+ // Defensive: an amount was supplied, so the gateway should have opened one.
109
+ throw new CliError('The gateway did not open a payment for that amount. Nothing was sent; try again.', 'PAYMENT_NOT_OPENED', EXIT.FAILED);
110
+ }
111
+ printOutput({
112
+ reference: intent.reference,
113
+ amount_usd: intent.amount_usd,
114
+ expires_at: intent.expires_at,
115
+ chain: target.chain,
116
+ chain_id: target.chain_id,
117
+ token_symbol: target.token_symbol,
118
+ token_address: target.token_address,
119
+ deposit_address: target.deposit_address,
120
+ min_confirmations: target.min_confirmations,
121
+ });
122
+ if (!isJsonMode()) {
123
+ human('');
124
+ human(` Send exactly ${intent.amount_usd} ${target.token_symbol} on ${target.chain} to:`);
125
+ human('');
126
+ human(` ${target.deposit_address}`);
127
+ human('');
128
+ human(` Reference ${intent.reference} · expires in ${minutesUntil(intent.expires_at)} min`);
129
+ human(' The exact amount is how we know the payment is yours, so send it to the cent.');
130
+ human(` Credited after ${target.min_confirmations} confirmation(s).`);
131
+ human('');
132
+ }
133
+ if (!opts.wait) {
134
+ hint('certen fund --no-wait was used; check later with certen balance');
135
+ return;
136
+ }
137
+ if (!isJsonMode()) {
138
+ human(' Waiting for your deposit. Ctrl-C is safe — the payment stays open.');
139
+ }
140
+ let lastSeen = '';
141
+ const final = await client.billing.waitForPayment(intent.reference, {
142
+ intervalMs: pollSec * 1_000,
143
+ timeoutMs: timeoutMin * 60_000,
144
+ onPoll: (s) => {
145
+ // Only speak when something changed, so a long wait is not a wall of text.
146
+ if (!isJsonMode() && s.status !== lastSeen) {
147
+ lastSeen = s.status;
148
+ if (s.status !== 'open')
149
+ human(` Payment ${s.status}.`);
150
+ }
151
+ },
152
+ });
153
+ if (final.status === 'matched') {
154
+ if (!isJsonMode()) {
155
+ const balance = await client.billing.balance().catch(() => null);
156
+ human(` Credited ${usd(final.amount_usd)}.`);
157
+ if (balance)
158
+ human(` Available now ${usd(balance.available_usd)}.`);
159
+ human('');
160
+ hint('Paying from this wallet again? Register it once in the portal and every '
161
+ + 'future deposit credits automatically: /portal');
162
+ }
163
+ return;
164
+ }
165
+ // Not credited. This is an ordinary outcome, not a crash — but the exit code
166
+ // has to say so, or a script will treat an expired payment as funded.
167
+ const why = final.status === 'open'
168
+ ? `still waiting after ${timeoutMin} min`
169
+ : `payment ${final.status}`;
170
+ throw new CliError(`Deposit not credited (${why}). Nothing was charged. `
171
+ + 'Check with: certen balance', 'DEPOSIT_NOT_CREDITED', EXIT.FAILED);
172
+ });
173
+ }
174
+ //# sourceMappingURL=billing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.js","sourceRoot":"","sources":["../../src/commands/billing.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { printOutput } from '../output.js';
1
+ import { printOutput, human } from '../output.js';
2
2
  import { resolvePassphrase, resolveNewPassphrase, PASSPHRASE_ENV_VAR } from '../passphrase.js';
3
3
  import { generateKey, listKeys, getKeyInfo, deleteKey, signHash, selfTest, keyPath, KEYS_DIR, } from '../keystore.js';
4
4
  /**
@@ -41,7 +41,7 @@ export function registerKeysCommands(program) {
41
41
  .action(() => {
42
42
  const all = listKeys();
43
43
  if (all.length === 0) {
44
- console.log(`(no keys in ${KEYS_DIR})`);
44
+ human(`(no keys in ${KEYS_DIR})`);
45
45
  return;
46
46
  }
47
47
  printOutput(all.map((k) => ({
@@ -96,7 +96,7 @@ export function registerKeysCommands(program) {
96
96
  // should not be deletable by an accidental Enter on a y/N prompt.
97
97
  const path = keyPath(name);
98
98
  deleteKey(name);
99
- console.log(`Deleted ${path}`);
99
+ human(`Deleted ${path}`);
100
100
  console.error('If this key was on a key page, it is still on that page — remove it there too.');
101
101
  });
102
102
  keys
@@ -1 +1 @@
1
- {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/commands/keys.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { Option } from 'commander';
1
2
  import { readFileSync } from 'node:fs';
2
3
  import { CertenClient } from '@certen.io/sdk';
3
4
  import { getApiKey, getApiUrl } from '../config.js';
@@ -42,6 +43,9 @@ export function registerTransactionCommands(program) {
42
43
  .option('--contract-address <addr...>', 'Contract addresses this intent touches')
43
44
  .option('--signer-key-page <url>', 'Which key page signs, e.g. acc://org.acme/book/2')
44
45
  .option('--signer-public-key <hex>', 'Which seat on the page signs (64 hex)')
46
+ // Validated here so a typo is caught before a request goes out, rather than surfacing from the
47
+ // proof service later with no obvious connection to the flag that caused it.
48
+ .addOption(new Option('--proof-class <class>', 'When the proof runs: on_demand starts now (~60-110s); on_cadence batches it (cheaper, slower)').choices(['on_demand', 'on_cadence']))
45
49
  .option('--idempotency-key <key>', 'Idempotency key (one is generated if omitted)')
46
50
  .option('--sign-with <key>', 'Local key: sign the returned hash and submit it in one step')
47
51
  .action(async (opts) => {
@@ -75,6 +79,7 @@ export function registerTransactionCommands(program) {
75
79
  intent,
76
80
  contractAddresses: opts.contractAddress,
77
81
  signerKeyPage: opts.signerKeyPage,
82
+ proofClass: opts.proofClass,
78
83
  signerPublicKey: opts.signerPublicKey ?? signer?.publicKey,
79
84
  idempotencyKey: opts.idempotencyKey,
80
85
  });
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/commands/transaction.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,KAAK,UAAU,SAAS;IACtB,OAAO,IAAI,YAAY,CAAC,EAAE,MAAM,EAAE,MAAM,SAAS,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,UAAU,CAAC,MAAe;IACjC,MAAM,CAAC,GAAG,MAGT,CAAC;IACF,OAAO,CAAC,CAAC,YAAY,EAAE,YAAY,IAAI,CAAC,CAAC,WAAW,EAAE,UAAU,IAAI,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC;AAChG,CAAC;AAED,SAAS,UAAU,CAAC,MAAe;IACjC,MAAM,CAAC,GAAG,MAAmD,CAAC;IAC9D,OAAO,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,QAAQ,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,OAAgB;IAC1D,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,uBAAuB,CAAC,CAAC;IAEtE,EAAE;SACC,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,gFAAgF,CAAC;QAC9F,qGAAqG;QACrG,iGAAiG;QACjG,uDAAuD;SACtD,cAAc,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;SACvD,MAAM,CAAC,iBAAiB,EAAE,qEAAqE,CAAC;SAChG,MAAM,CAAC,sBAAsB,EAAE,cAAc,EAAE,YAAY,CAAC;SAC5D,MAAM,CAAC,oBAAoB,EAAE,0CAA0C,CAAC;SACxE,MAAM,CAAC,kBAAkB,EAAE,2DAA2D,CAAC;SACvF,MAAM,CAAC,gBAAgB,EAAE,qBAAqB,CAAC;SAC/C,MAAM,CAAC,mBAAmB,EAAE,+CAA+C,CAAC;SAC5E,MAAM,CAAC,kBAAkB,EAAE,cAAc,CAAC;SAC1C,MAAM,CAAC,8BAA8B,EAAE,wCAAwC,CAAC;SAChF,MAAM,CAAC,yBAAyB,EAAE,kDAAkD,CAAC;SACrF,MAAM,CAAC,2BAA2B,EAAE,uCAAuC,CAAC;SAC5E,MAAM,CAAC,yBAAyB,EAAE,+CAA+C,CAAC;SAClF,MAAM,CAAC,mBAAmB,EAAE,6DAA6D,CAAC;SAC1F,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QAEjC,wFAAwF;QACxF,mFAAmF;QACnF,4CAA4C;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAEzE,IAAI,MAA+B,CAAC;QACpC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;gBACrC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;gBAC5C,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;YAChB,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;YACxG,CAAC;YACD,MAAM,GAAG;gBACP,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,WAAW,EAAE,IAAI,CAAC,IAAI;gBACtB,SAAS,EAAE,IAAI,CAAC,EAAE;gBAClB,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC3B,WAAW,EAAE,IAAI,CAAC,KAAK;aACxB,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC;YAC7C,UAAU,EAAE,IAAI,CAAC,QAAQ;YACzB,MAAM;YACN,iBAAiB,EAAE,IAAI,CAAC,eAAe;YACvC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,MAAM,EAAE,SAAS;YAC1D,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,WAAW,CAAC,MAA4C,CAAC,CAAC;YAC1D,OAAO;QACT,CAAC;QAED,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvB,2FAA2F;YAC3F,0EAA0E;YAC1E,WAAW,CAAC,MAA4C,CAAC,CAAC;YAC1D,MAAM,IAAI,KAAK,CACb,yFAAyF;kBACvF,wEAAwE,CAC3E,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,QAAQ,EAAE;YAChE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;YAC5B,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAC,CAAC;QACH,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,EAAE;SACC,OAAO,CAAC,WAAW,CAAC;SACpB,WAAW,CAAC,sCAAsC,CAAC;SACnD,MAAM,CAAC,mBAAmB,EAAE,uCAAuC,CAAC;SACpE,MAAM,CAAC,cAAc,EAAE,4DAA4D,CAAC;SACpF,MAAM,CAAC,mBAAmB,EAAE,mDAAmD,CAAC;SAChF,MAAM,CAAC,oBAAoB,EAAE,6CAA6C,CAAC;SAC3E,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,IAAI,EAAE,EAAE;QACjC,2FAA2F;QAC3F,yFAAyF;QACzF,0CAA0C;QAC1C,IAAI,SAAiB,CAAC;QACtB,IAAI,SAAiB,CAAC;QAEtB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;YACzF,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CACb,mFAAmF;sBACjF,wDAAwD,CAC3D,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAClD,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;YACnG,CAAC;YACD,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;YAC3B,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAC7B,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,CAAC;QACtF,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,EAAE;SACC,OAAO,CAAC,aAAa,CAAC;SACtB,WAAW,CAAC,wBAAwB,CAAC;SACrC,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChD,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEL,EAAE;SACC,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,mBAAmB,CAAC;SAChC,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,QAAQ,CAAC;SAC9C,MAAM,CAAC,cAAc,EAAE,QAAQ,EAAE,QAAQ,CAAC;SAC1C,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QACrB,MAAM,MAAM,GAAG,MAAM,SAAS,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC;YAC3C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC,CAAC;QACH,WAAW,CAAC,MAA4C,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/commands/transaction.ts"],"names":[],"mappings":"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"}
package/dist/config.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { readFileSync, writeFileSync, mkdirSync, existsSync, chmodSync, statSync } from 'fs';
2
2
  import { join } from 'path';
3
3
  import { homedir } from 'os';
4
+ import { UsageError } from './errors.js';
4
5
  const CONFIG_DIR = join(homedir(), '.certen');
5
6
  const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
6
7
  export function readConfig() {
@@ -86,19 +87,17 @@ export async function getApiKey() {
86
87
  return v;
87
88
  }
88
89
  else {
89
- console.error('storage=keyring requested but `keytar` is not installed; install it or set CERTEN_API_KEY.');
90
- process.exit(1);
90
+ throw new UsageError('storage=keyring requested but `keytar` is not installed; install it or set CERTEN_API_KEY.', 'KEYRING_UNAVAILABLE');
91
91
  }
92
92
  }
93
93
  if (cfg.api_key) {
94
94
  if (!configFileIsSecure()) {
95
- console.error('refusing to read ~/.certen/config.json — file permissions are not 0600. Run `certen auth login` again to fix.');
96
- process.exit(1);
95
+ throw new UsageError('refusing to read ~/.certen/config.json — file permissions are not 0600. '
96
+ + 'Run `certen auth login` again to fix.', 'CONFIG_PERMISSIONS');
97
97
  }
98
98
  return cfg.api_key;
99
99
  }
100
- console.error('No API key configured. Run "certen auth login --api-key <key>" or set CERTEN_API_KEY.');
101
- process.exit(1);
100
+ throw new UsageError('No API key configured. Run "certen auth login --api-key <key>" or set CERTEN_API_KEY.', 'NO_API_KEY');
102
101
  }
103
102
  export async function setApiKey(apiKey, useKeyring) {
104
103
  const prefix = apiKey.substring(0, 12);
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Exit codes and the local error taxonomy.
3
+ *
4
+ * The CLI used to exit `1` for everything — a bad flag, a rejected request, and an unreachable
5
+ * gateway were indistinguishable without reading English off stderr. An automated caller cannot
6
+ * make a retry decision from that: "you passed a malformed address" and "the gateway is down" want
7
+ * opposite responses, and only one of them is worth retrying.
8
+ *
9
+ * These four codes are a contract. See docs/CLI-CONTRACT.md.
10
+ */
11
+ export declare const EXIT: {
12
+ /** Success. */
13
+ readonly OK: 0;
14
+ /** The request was well-formed and the gateway answered, but the operation did not succeed. */
15
+ readonly FAILED: 1;
16
+ /** The invocation was wrong: unknown command, missing flag, no API key configured. */
17
+ readonly USAGE: 2;
18
+ /** The gateway could not be reached at all. Nothing was submitted. */
19
+ readonly UNREACHABLE: 3;
20
+ };
21
+ export type ExitCode = (typeof EXIT)[keyof typeof EXIT];
22
+ /**
23
+ * An error raised by the CLI itself rather than by the gateway.
24
+ *
25
+ * `code` is machine-readable and lives in the same namespace as the gateway's codes, so a caller
26
+ * branching on `error.code` does not need to know whether the failure was local or remote.
27
+ */
28
+ export declare class CliError extends Error {
29
+ readonly code: string;
30
+ readonly exitCode: ExitCode;
31
+ readonly retryable: boolean;
32
+ constructor(message: string, code: string, exitCode?: ExitCode, retryable?: boolean);
33
+ }
34
+ /** A wrong invocation: exits 2, never retryable. */
35
+ export declare class UsageError extends CliError {
36
+ constructor(message: string, code?: string);
37
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Exit codes and the local error taxonomy.
3
+ *
4
+ * The CLI used to exit `1` for everything — a bad flag, a rejected request, and an unreachable
5
+ * gateway were indistinguishable without reading English off stderr. An automated caller cannot
6
+ * make a retry decision from that: "you passed a malformed address" and "the gateway is down" want
7
+ * opposite responses, and only one of them is worth retrying.
8
+ *
9
+ * These four codes are a contract. See docs/CLI-CONTRACT.md.
10
+ */
11
+ export const EXIT = {
12
+ /** Success. */
13
+ OK: 0,
14
+ /** The request was well-formed and the gateway answered, but the operation did not succeed. */
15
+ FAILED: 1,
16
+ /** The invocation was wrong: unknown command, missing flag, no API key configured. */
17
+ USAGE: 2,
18
+ /** The gateway could not be reached at all. Nothing was submitted. */
19
+ UNREACHABLE: 3,
20
+ };
21
+ /**
22
+ * An error raised by the CLI itself rather than by the gateway.
23
+ *
24
+ * `code` is machine-readable and lives in the same namespace as the gateway's codes, so a caller
25
+ * branching on `error.code` does not need to know whether the failure was local or remote.
26
+ */
27
+ export class CliError extends Error {
28
+ code;
29
+ exitCode;
30
+ retryable;
31
+ constructor(message, code, exitCode = EXIT.FAILED, retryable = false) {
32
+ super(message);
33
+ this.name = 'CliError';
34
+ this.code = code;
35
+ this.exitCode = exitCode;
36
+ this.retryable = retryable;
37
+ }
38
+ }
39
+ /** A wrong invocation: exits 2, never retryable. */
40
+ export class UsageError extends CliError {
41
+ constructor(message, code = 'USAGE_ERROR') {
42
+ super(message, code, EXIT.USAGE, false);
43
+ this.name = 'UsageError';
44
+ }
45
+ }
46
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,eAAe;IACf,EAAE,EAAE,CAAC;IACL,+FAA+F;IAC/F,MAAM,EAAE,CAAC;IACT,sFAAsF;IACtF,KAAK,EAAE,CAAC;IACR,sEAAsE;IACtE,WAAW,EAAE,CAAC;CACN,CAAC;AAIX;;;;;GAKG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,QAAQ,CAAW;IACnB,SAAS,CAAU;IAE5B,YAAY,OAAe,EAAE,IAAY,EAAE,WAAqB,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,KAAK;QAC5F,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED,oDAAoD;AACpD,MAAM,OAAO,UAAW,SAAQ,QAAQ;IACtC,YAAY,OAAe,EAAE,IAAI,GAAG,aAAa;QAC/C,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function commandTree(program: Command, version: string): string;
@@ -0,0 +1,51 @@
1
+ function optionNode(o) {
2
+ return {
3
+ flags: o.flags,
4
+ name: o.attributeName ? o.attributeName() : (o.long ?? o.short ?? o.flags).replace(/^--?/, ''),
5
+ description: o.description ?? '',
6
+ required: Boolean(o.mandatory),
7
+ // `required` on a commander Option means "this flag takes a mandatory value", not "this flag
8
+ // must be present" — that is `mandatory`. Conflating them is an easy and very confusing bug.
9
+ takesValue: Boolean(o.required || o.optional),
10
+ ...(o.defaultValue !== undefined ? { default: o.defaultValue } : {}),
11
+ };
12
+ }
13
+ function argumentsOf(cmd) {
14
+ // `registeredArguments` is commander >= 12; `_args` is the older internal. Fall back rather than
15
+ // throw, so a commander bump degrades the help tree instead of breaking the command.
16
+ const raw = (cmd.registeredArguments
17
+ ?? cmd._args
18
+ ?? []);
19
+ return raw.map((a) => ({
20
+ name: a.name(),
21
+ required: Boolean(a.required),
22
+ description: a.description ?? '',
23
+ }));
24
+ }
25
+ function walk(cmd, prefix) {
26
+ const path = [...prefix, cmd.name()].filter(Boolean);
27
+ return {
28
+ name: cmd.name(),
29
+ description: cmd.description(),
30
+ path: path.join(' '),
31
+ arguments: argumentsOf(cmd),
32
+ options: cmd.options.map(optionNode),
33
+ commands: cmd.commands.map((c) => walk(c, path)),
34
+ };
35
+ }
36
+ export function commandTree(program, version) {
37
+ return JSON.stringify({
38
+ ok: true,
39
+ data: {
40
+ ...walk(program, []),
41
+ version,
42
+ exitCodes: {
43
+ 0: 'ok',
44
+ 1: 'operation failed',
45
+ 2: 'usage error',
46
+ 3: 'gateway unreachable',
47
+ },
48
+ },
49
+ });
50
+ }
51
+ //# sourceMappingURL=help-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help-json.js","sourceRoot":"","sources":["../src/help-json.ts"],"names":[],"mappings":"AAoDA,SAAS,UAAU,CAAC,CAAsB;IACxC,OAAO;QACL,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC9F,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;QAChC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QAC9B,6FAA6F;QAC7F,6FAA6F;QAC7F,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,CAAC;QAC7C,GAAG,CAAC,CAAC,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrE,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,iGAAiG;IACjG,qFAAqF;IACrF,MAAM,GAAG,GACP,CAAE,GAAoE,CAAC,mBAAmB;WACpF,GAAsD,CAAC,KAAK;WAC7D,EAAE,CAAC,CAAC;IACX,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACrB,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACd,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;QAC7B,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,EAAE;KACjC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,IAAI,CAAC,GAAY,EAAE,MAAgB;IAC1C,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrD,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE;QAChB,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE;QAC9B,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QACpB,SAAS,EAAE,WAAW,CAAC,GAAG,CAAC;QAC3B,OAAO,EAAG,GAAG,CAAC,OAA4C,CAAC,GAAG,CAAC,UAAU,CAAC;QAC1E,QAAQ,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAY,EAAE,IAAI,CAAC,CAAC;KAC5D,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAgB,EAAE,OAAe;IAC3D,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,EAAE,EAAE,IAAI;QACR,IAAI,EAAE;YACJ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;YACpB,OAAO;YACP,SAAS,EAAE;gBACT,CAAC,EAAE,IAAI;gBACP,CAAC,EAAE,kBAAkB;gBACrB,CAAC,EAAE,aAAa;gBAChB,CAAC,EAAE,qBAAqB;aACzB;SACF;KACF,CAAC,CAAC;AACL,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,5 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ import { Command } from 'commander';
3
+ import { type ExitCode } from './errors.js';
4
+ export declare function buildProgram(): Command;
5
+ export declare function run(argv: string[]): Promise<ExitCode>;
package/dist/index.js CHANGED
@@ -1,9 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { readFileSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
- import { fileURLToPath } from 'node:url';
5
- import { Command } from 'commander';
4
+ import { fileURLToPath, pathToFileURL } from 'node:url';
5
+ import { Command, CommanderError } from 'commander';
6
6
  import { CertenError } from '@certen.io/sdk';
7
+ import { EXIT } from './errors.js';
8
+ import { setJsonMode, flushSuccess, emitFailure } from './output.js';
9
+ import { commandTree } from './help-json.js';
7
10
  /** Read the version from package.json — dist/ sits one level below the manifest. */
8
11
  function readVersion() {
9
12
  try {
@@ -22,43 +25,105 @@ import { registerPendingCommands } from './commands/pending.js';
22
25
  import { registerGovernanceCommands } from './commands/governance.js';
23
26
  import { registerPortfolioCommands } from './commands/portfolio.js';
24
27
  import { registerAdminCommands } from './commands/admin.js';
25
- const program = new Command();
26
- program
27
- .name('certen')
28
- .description('CERTEN Gateway CLI')
29
- // Was hardcoded to 0.1.0 while package.json said 0.2.0, so `certen --version` reported a
30
- // release that does not exist. Read it from the manifest so the two cannot drift again.
31
- .version(readVersion());
32
- registerAuthCommands(program);
33
- registerKeysCommands(program);
34
- registerIdentityCommands(program);
35
- registerTransactionCommands(program);
36
- registerPendingCommands(program);
37
- registerGovernanceCommands(program);
38
- registerPortfolioCommands(program);
39
- registerAdminCommands(program);
40
- // Global error handler
41
- program.hook('preAction', () => { });
42
- program.exitOverride();
43
- async function main() {
28
+ import { registerBillingCommands } from './commands/billing.js';
29
+ const VERSION = readVersion();
30
+ export function buildProgram() {
31
+ const program = new Command();
32
+ program
33
+ .name('certen')
34
+ .description('CERTEN Gateway CLI')
35
+ // Was hardcoded to 0.1.0 while package.json said 0.2.0, so `certen --version` reported a
36
+ // release that does not exist. Read it from the manifest so the two cannot drift again.
37
+ .version(VERSION)
38
+ // Declared so it appears in --help. It is stripped from argv before parsing (see run()), because
39
+ // a global flag that may appear after a subcommand is not something commander models.
40
+ .option('--json', 'Emit one JSON envelope on stdout; human output goes to stderr');
41
+ registerAuthCommands(program);
42
+ registerKeysCommands(program);
43
+ registerIdentityCommands(program);
44
+ registerTransactionCommands(program);
45
+ registerPendingCommands(program);
46
+ registerGovernanceCommands(program);
47
+ registerPortfolioCommands(program);
48
+ registerBillingCommands(program);
49
+ registerAdminCommands(program);
50
+ // Every command, not just the root. `exitOverride()` is NOT inherited by subcommands, so without
51
+ // this walk a missing required flag on `identity create` called process.exit(1) inside commander:
52
+ // stdout stayed empty, no envelope was ever emitted, and a usage error was indistinguishable from
53
+ // a failed request. Every nested command has to opt in explicitly.
54
+ applyExitOverride(program);
55
+ return program;
56
+ }
57
+ function applyExitOverride(cmd) {
58
+ cmd.exitOverride();
59
+ for (const sub of cmd.commands)
60
+ applyExitOverride(sub);
61
+ }
62
+ /**
63
+ * Map a thrown value to an exit code, and emit the matching envelope.
64
+ *
65
+ * The four codes exist so an automated caller never has to parse English to decide what to do:
66
+ * `2` means fix the invocation, `3` means the gateway was unreachable and nothing was submitted,
67
+ * `1` means the gateway answered and said no.
68
+ */
69
+ function handleError(err) {
70
+ if (err instanceof CommanderError) {
71
+ // --help and --version are successful terminations that commander reports by throwing.
72
+ if (err.exitCode === 0 || err.code === 'commander.helpDisplayed' || err.code === 'commander.version') {
73
+ return EXIT.OK;
74
+ }
75
+ return emitFailure({
76
+ message: err.message.replace(/^error: /, ''),
77
+ code: 'USAGE_ERROR',
78
+ exitCode: EXIT.USAGE,
79
+ });
80
+ }
81
+ if (err instanceof CertenError) {
82
+ // Pass the ERROR, not a copy of its fields.
83
+ //
84
+ // This used to flatten it into an object literal. The literal carried the same
85
+ // values but destroyed the class identity, so a 402 reached the reporter as an
86
+ // anonymous shape and its payment target was silently dropped — the refusal
87
+ // printed a code and a message while the fix sat unread on the error.
88
+ //
89
+ // Nothing is lost by passing the instance: message, code, status and requestId
90
+ // are all readable on it, and `isRetryable` is a getter, so the SDK's own retry
91
+ // judgement still reaches both transports.
92
+ return emitFailure(err);
93
+ }
94
+ return emitFailure(err);
95
+ }
96
+ export async function run(argv) {
97
+ // `--json` is resolved before parsing so it applies to every code path, including failures that
98
+ // happen while resolving credentials — those must be reportable in the envelope too.
99
+ const json = argv.includes('--json');
100
+ setJsonMode(json);
101
+ const cleanArgv = argv.filter((a) => a !== '--json');
102
+ const program = buildProgram();
103
+ // `certen --help --json` answers "what can this CLI do" in one call, instead of scraping help
104
+ // text once per subcommand.
105
+ if (json && (cleanArgv.includes('--help') || cleanArgv.includes('-h'))) {
106
+ process.stdout.write(`${commandTree(program, VERSION)}\n`);
107
+ return EXIT.OK;
108
+ }
44
109
  try {
45
- await program.parseAsync(process.argv);
110
+ await program.parseAsync(cleanArgv);
111
+ flushSuccess();
112
+ return EXIT.OK;
46
113
  }
47
114
  catch (err) {
48
- if (err instanceof CertenError) {
49
- console.error(`Error [${err.code}]: ${err.message}`);
50
- process.exit(1);
51
- }
52
- if (err instanceof Error) {
53
- // Commander exit override throws for --help etc
54
- if (err.exitCode === 0)
55
- return;
56
- console.error(`Error: ${err.message}`);
57
- process.exit(1);
58
- }
59
- console.error('Unknown error:', err);
60
- process.exit(1);
115
+ return handleError(err);
61
116
  }
62
117
  }
63
- main();
118
+ /* c8 ignore start — entrypoint wiring, exercised by the conformance suite as a subprocess */
119
+ // Run only when executed as the binary, not when imported by a test. `pathToFileURL` is what makes
120
+ // this correct on Windows, where a naive `file://` + path concatenation produces a URL that never
121
+ // matches `import.meta.url`.
122
+ const invokedDirectly = Boolean(process.argv[1]) && import.meta.url === pathToFileURL(process.argv[1]).href;
123
+ if (invokedDirectly) {
124
+ run(process.argv).then((code) => {
125
+ process.exitCode = code;
126
+ });
127
+ }
128
+ /* c8 ignore stop */
64
129
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/output.d.ts CHANGED
@@ -1,6 +1,36 @@
1
+ import { type ExitCode } from './errors.js';
2
+ export declare function setJsonMode(on: boolean): void;
3
+ export declare function isJsonMode(): boolean;
4
+ /** Test seam: reset module state between cases. */
5
+ export declare function resetOutput(): void;
1
6
  /**
2
- * Print data as an aligned table or JSON depending on user preference.
7
+ * Print a result. In JSON mode this buffers; call `flushSuccess()` once the command completes.
3
8
  */
4
9
  export declare function printOutput(data: Record<string, unknown>[] | Record<string, unknown>, opts?: {
5
10
  forceJson?: boolean;
6
11
  }): void;
12
+ /**
13
+ * A human-facing note — "API key saved", "(no keys)".
14
+ *
15
+ * In JSON mode this goes to stderr, because stdout is reserved for the single envelope. In table
16
+ * mode it is ordinary output and goes to stdout.
17
+ */
18
+ export declare function human(message: string): void;
19
+ /** A hint or warning. Always stderr — it is never the result of the command. */
20
+ export declare function hint(message: string): void;
21
+ /**
22
+ * Emit the success envelope. No-op outside JSON mode, and safe to call more than once.
23
+ *
24
+ * A command that produced no payload still emits `{"ok":true,"data":null}` rather than nothing, so
25
+ * a caller can always parse stdout instead of special-casing empty output.
26
+ */
27
+ export declare function flushSuccess(): void;
28
+ /**
29
+ * Emit the failure envelope (JSON mode) or a human error line (table mode), and return the exit code.
30
+ *
31
+ * `retryable` is taken from the SDK's own `CertenError.isRetryable` wherever the error came from the
32
+ * gateway, so the CLI and the SDK hand an automated caller the identical retry decision. That
33
+ * equivalence is the property worth having: a script can switch transports without re-deriving which
34
+ * failures are worth another attempt.
35
+ */
36
+ export declare function emitFailure(err: unknown): ExitCode;
package/dist/output.js CHANGED
@@ -1,13 +1,162 @@
1
+ import { CertenPaymentRequiredError } from '@certen.io/sdk';
1
2
  import { getOutputFormat } from './config.js';
3
+ import { CliError, EXIT } from './errors.js';
2
4
  /**
3
- * Print data as an aligned table or JSON depending on user preference.
5
+ * Two output modes with different audiences and different guarantees.
6
+ *
7
+ * Table mode is for humans and is NOT a contract — column widths and wording may change.
8
+ *
9
+ * JSON mode is a machine contract: exactly one envelope object on stdout and nothing else, every
10
+ * human-facing line on stderr, and an exit code that says which kind of failure occurred. See
11
+ * docs/CLI-CONTRACT.md. The single-object guarantee is why payloads are buffered rather than
12
+ * printed as they arrive: a command that prints twice would otherwise emit two top-level objects
13
+ * and break every streaming JSON parser pointed at it.
14
+ */
15
+ let jsonMode = false;
16
+ /** Payloads collected in JSON mode, flushed as one envelope when the command finishes. */
17
+ let collected = [];
18
+ let flushed = false;
19
+ export function setJsonMode(on) {
20
+ jsonMode = on;
21
+ }
22
+ export function isJsonMode() {
23
+ return jsonMode;
24
+ }
25
+ /** Test seam: reset module state between cases. */
26
+ export function resetOutput() {
27
+ jsonMode = false;
28
+ collected = [];
29
+ flushed = false;
30
+ }
31
+ /**
32
+ * Print a result. In JSON mode this buffers; call `flushSuccess()` once the command completes.
4
33
  */
5
34
  export function printOutput(data, opts) {
35
+ if (jsonMode) {
36
+ collected.push(data);
37
+ return;
38
+ }
6
39
  const format = opts?.forceJson ? 'json' : getOutputFormat();
7
40
  if (format === 'json') {
8
41
  console.log(JSON.stringify(data, null, 2));
9
42
  return;
10
43
  }
44
+ printTable(data);
45
+ }
46
+ /**
47
+ * A human-facing note — "API key saved", "(no keys)".
48
+ *
49
+ * In JSON mode this goes to stderr, because stdout is reserved for the single envelope. In table
50
+ * mode it is ordinary output and goes to stdout.
51
+ */
52
+ export function human(message) {
53
+ if (jsonMode)
54
+ console.error(message);
55
+ else
56
+ console.log(message);
57
+ }
58
+ /** A hint or warning. Always stderr — it is never the result of the command. */
59
+ export function hint(message) {
60
+ console.error(message);
61
+ }
62
+ /**
63
+ * Emit the success envelope. No-op outside JSON mode, and safe to call more than once.
64
+ *
65
+ * A command that produced no payload still emits `{"ok":true,"data":null}` rather than nothing, so
66
+ * a caller can always parse stdout instead of special-casing empty output.
67
+ */
68
+ export function flushSuccess() {
69
+ if (!jsonMode || flushed)
70
+ return;
71
+ flushed = true;
72
+ const data = collected.length === 0 ? null : collected.length === 1 ? collected[0] : collected;
73
+ process.stdout.write(`${JSON.stringify({ ok: true, data })}\n`);
74
+ }
75
+ /**
76
+ * Emit the failure envelope (JSON mode) or a human error line (table mode), and return the exit code.
77
+ *
78
+ * `retryable` is taken from the SDK's own `CertenError.isRetryable` wherever the error came from the
79
+ * gateway, so the CLI and the SDK hand an automated caller the identical retry decision. That
80
+ * equivalence is the property worth having: a script can switch transports without re-deriving which
81
+ * failures are worth another attempt.
82
+ */
83
+ export function emitFailure(err) {
84
+ const e = (err ?? {});
85
+ const message = e.message ?? String(err);
86
+ const code = e.code ?? 'UNKNOWN_ERROR';
87
+ const retryable = e instanceof CliError ? e.retryable : Boolean(e.isRetryable);
88
+ const exitCode = resolveExitCode(e);
89
+ // A refusal for lack of funds is the one failure that carries its own fix, so it
90
+ // is rendered rather than reduced to a code and a message. The developer is
91
+ // already in a terminal; the next command belongs there, not in documentation.
92
+ const payment = err instanceof CertenPaymentRequiredError ? err : null;
93
+ if (jsonMode) {
94
+ flushed = true;
95
+ process.stdout.write(`${JSON.stringify({
96
+ ok: false,
97
+ error: {
98
+ code,
99
+ message,
100
+ retryable,
101
+ ...(e.status !== undefined ? { status: e.status } : {}),
102
+ ...(e.requestId ? { requestId: e.requestId } : {}),
103
+ // Additive: a consumer that ignores unknown keys is unaffected, and one
104
+ // that wants to settle automatically no longer has to parse prose.
105
+ ...(payment
106
+ ? {
107
+ shortfall_usd: payment.shortfallUsd,
108
+ quote_id: payment.quoteId,
109
+ resolve: payment.resolution,
110
+ }
111
+ : {}),
112
+ },
113
+ })}\n`);
114
+ }
115
+ else {
116
+ console.error(code === 'UNKNOWN_ERROR' ? `Error: ${message}` : `Error [${code}]: ${message}`);
117
+ if (payment)
118
+ emitPaymentFix(payment);
119
+ }
120
+ return exitCode;
121
+ }
122
+ /**
123
+ * Print the way out of a 402.
124
+ *
125
+ * All on stderr: it is guidance, not the result of the command, and a caller
126
+ * piping stdout must still get clean output (or, in JSON mode, exactly one
127
+ * envelope). The closing line matters as much as the address — a developer whose
128
+ * request was refused needs to know nothing was charged and nothing started.
129
+ */
130
+ function emitPaymentFix(payment) {
131
+ console.error('');
132
+ console.error(` ${payment.summary}`);
133
+ const r = payment.resolution;
134
+ if (r) {
135
+ console.error('');
136
+ console.error(` Send exactly ${r.amount_usd} USD on ${r.chain} to:`);
137
+ console.error(` ${r.to_address}`);
138
+ console.error(` Reference ${r.payment_intent}`);
139
+ console.error('');
140
+ console.error(` Or run: ${r.cli_command}`);
141
+ console.error(` Portal: ${r.portal_url}`);
142
+ }
143
+ if (payment.quoteId) {
144
+ console.error('');
145
+ console.error(` Then retry with --quote-id ${payment.quoteId} to keep this price.`);
146
+ }
147
+ console.error('');
148
+ console.error(' Nothing was charged and no work was started.');
149
+ }
150
+ function resolveExitCode(e) {
151
+ if (typeof e.exitCode === 'number')
152
+ return e.exitCode;
153
+ // status 0 is how the SDK reports "the request never reached the gateway".
154
+ if (e.code === 'NETWORK_ERROR' || e.status === 0)
155
+ return EXIT.UNREACHABLE;
156
+ return EXIT.FAILED;
157
+ }
158
+ // ── table rendering (human mode only) ───────────────────────────────────────────────────────────
159
+ function printTable(data) {
11
160
  // Single object: print key-value pairs
12
161
  if (!Array.isArray(data)) {
13
162
  const entries = Object.entries(data);
@@ -1 +1 @@
1
- {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAiB,MAAM,aAAa,CAAC;AAE5D;;;;;;;;;;GAUG;AAEH,IAAI,QAAQ,GAAG,KAAK,CAAC;AACrB,0FAA0F;AAC1F,IAAI,SAAS,GAAc,EAAE,CAAC;AAC9B,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB,MAAM,UAAU,WAAW,CAAC,EAAW;IACrC,QAAQ,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,WAAW;IACzB,QAAQ,GAAG,KAAK,CAAC;IACjB,SAAS,GAAG,EAAE,CAAC;IACf,OAAO,GAAG,KAAK,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,IAAyD,EACzD,IAA8B;IAE9B,IAAI,QAAQ,EAAE,CAAC;QACb,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;IAC5D,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,UAAU,CAAC,IAAI,CAAC,CAAC;AACnB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,OAAe;IACnC,IAAI,QAAQ;QAAE,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;;QAChC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY;IAC1B,IAAI,CAAC,QAAQ,IAAI,OAAO;QAAE,OAAO;IACjC,OAAO,GAAG,IAAI,CAAC;IACf,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC;AAClE,CAAC;AAWD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE,CAAc,CAAC;IACnC,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC;IACvC,MAAM,SAAS,GAAG,CAAC,YAAY,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAC/E,MAAM,QAAQ,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;IAEpC,iFAAiF;IACjF,4EAA4E;IAC5E,+EAA+E;IAC/E,MAAM,OAAO,GAAG,GAAG,YAAY,0BAA0B,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;IAEvE,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,CAAC,SAAS,CAAC;YAChB,EAAE,EAAE,KAAK;YACT,KAAK,EAAE;gBACL,IAAI;gBACJ,OAAO;gBACP,SAAS;gBACT,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvD,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClD,wEAAwE;gBACxE,mEAAmE;gBACnE,GAAG,CAAC,OAAO;oBACT,CAAC,CAAC;wBACA,aAAa,EAAE,OAAO,CAAC,YAAY;wBACnC,QAAQ,EAAE,OAAO,CAAC,OAAO;wBACzB,OAAO,EAAE,OAAO,CAAC,UAAU;qBAC5B;oBACD,CAAC,CAAC,EAAE,CAAC;aACR;SACF,CAAC,IAAI,CACP,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC,CAAC,UAAU,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;QAC9F,IAAI,OAAO;YAAE,cAAc,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,OAAmC;IACzD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,KAAK,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAEtC,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;IAC7B,IAAI,CAAC,EAAE,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,UAAU,WAAW,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;QACtE,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC;QACjD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,gCAAgC,OAAO,CAAC,OAAO,sBAAsB,CAAC,CAAC;IACvF,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,eAAe,CAAC,CAAY;IACnC,IAAI,OAAO,CAAC,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,QAAoB,CAAC;IAClE,2EAA2E;IAC3E,IAAI,CAAC,CAAC,IAAI,KAAK,eAAe,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1E,OAAO,IAAI,CAAC,MAAM,CAAC;AACrB,CAAC;AAED,mGAAmG;AAEnG,SAAS,UAAU,CAAC,IAAyD;IAC3E,uCAAuC;IACvC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;YACnC,MAAM,YAAY,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAC7F,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO;IACT,CAAC;IAED,qBAAqB;IACrB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC;IAC3B,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,SAAS;IACT,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAElE,OAAO;IACP,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC"}
package/package.json CHANGED
@@ -1,56 +1,57 @@
1
- {
2
- "name": "@certen.io/cli",
3
- "version": "0.3.1",
4
- "description": "Command line for the CERTEN Gateway API",
5
- "license": "MIT",
6
- "type": "module",
7
- "keywords": [
8
- "certen",
9
- "accumulate",
10
- "cli",
11
- "blockchain"
12
- ],
13
- "homepage": "https://github.com/certenIO/certen-sdk#readme",
14
- "repository": {
15
- "type": "git",
16
- "url": "git+https://github.com/certenIO/certen-sdk.git",
17
- "directory": "packages/cli"
18
- },
19
- "bugs": {
20
- "url": "https://github.com/certenIO/certen-sdk/issues"
21
- },
22
- "engines": {
23
- "node": ">=18"
24
- },
25
- "bin": {
26
- "certen": "dist/index.js"
27
- },
28
- "//files": "Build output plus docs. Without this npm ships the whole directory, including src/ and test/.",
29
- "files": [
30
- "dist/",
31
- "README.md",
32
- "LICENSE"
33
- ],
34
- "scripts": {
35
- "build": "tsc",
36
- "test": "vitest run",
37
- "typecheck": "tsc --noEmit",
38
- "//prepack": "Build before packing so the published bin can never point at a missing dist/index.js.",
39
- "prepack": "npm run build",
40
- "prepublishOnly": "npm run build && npm test"
41
- },
42
- "publishConfig": {
43
- "access": "public"
44
- },
45
- "//dependencies": "@certen.io/sdk MUST be a version range, not file:../sdk. A published package carrying a file: dependency installs and then fails to resolve on the consumer's machine, because that path does not exist there. Local development uses `npm link` or a workspace instead.",
46
- "dependencies": {
47
- "@certen.io/sdk": "^0.3.1",
48
- "commander": "^12.0.0"
49
- },
50
- "devDependencies": {
51
- "typescript": "^5.5.0",
52
- "vitest": "^1.6.1",
53
- "@types/node": "^22.0.0"
54
- },
55
- "//publishConfig": "Provenance is passed as --provenance by .github/workflows/release.yml. Setting it here instead would break every publish outside CI with an error that does not explain itself."
56
- }
1
+ {
2
+ "name": "@certen.io/cli",
3
+ "version": "0.5.0",
4
+ "description": "Command line for the CERTEN Gateway API",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "keywords": [
8
+ "certen",
9
+ "accumulate",
10
+ "cli",
11
+ "blockchain"
12
+ ],
13
+ "homepage": "https://github.com/certenIO/certen-sdk#readme",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/certenIO/certen-sdk.git",
17
+ "directory": "packages/cli"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/certenIO/certen-sdk/issues"
21
+ },
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "bin": {
26
+ "certen": "dist/index.js"
27
+ },
28
+ "//files": "Build output plus docs. Without this npm ships the whole directory, including src/ and test/.",
29
+ "files": [
30
+ "dist/",
31
+ "CHANGELOG.md",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "scripts": {
36
+ "build": "tsc",
37
+ "test": "vitest run",
38
+ "typecheck": "tsc --noEmit",
39
+ "//prepack": "Build before packing so the published bin can never point at a missing dist/index.js.",
40
+ "prepack": "npm run build",
41
+ "prepublishOnly": "npm run build && npm test"
42
+ },
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "//dependencies": "@certen.io/sdk MUST be a version range, not file:../sdk. A published package carrying a file: dependency installs and then fails to resolve on the consumer's machine, because that path does not exist there. Local development uses `npm link` or a workspace instead.",
47
+ "dependencies": {
48
+ "@certen.io/sdk": "^0.5.0",
49
+ "commander": "^12.0.0"
50
+ },
51
+ "devDependencies": {
52
+ "typescript": "^5.5.0",
53
+ "vitest": "^1.6.1",
54
+ "@types/node": "^22.0.0"
55
+ },
56
+ "//publishConfig": "Provenance is passed as --provenance by .github/workflows/release.yml. Setting it here instead would break every publish outside CI with an error that does not explain itself."
57
+ }