@settlemint/dalp-cli 3.1.32-main.42864119477 → 3.1.32-main.42894513068

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@settlemint/dalp-cli",
3
- "version": "3.1.32-main.42864119477",
3
+ "version": "3.1.32-main.42894513068",
4
4
  "private": false,
5
5
  "description": "CLI for the Digital Asset Lifecycle Platform — manage tokens, identities, compliance, and more from the command line.",
6
6
  "homepage": "https://settlemint.com",
@@ -50,14 +50,14 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@modelcontextprotocol/server": "2.4.0",
53
- "@settlemint/dalp-sdk": "3.1.32-main.42864119477",
53
+ "@settlemint/dalp-sdk": "3.1.32-main.42894513068",
54
54
  "incur": "0.7.1",
55
55
  "zod": "4.6.7"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@arethetypeswrong/cli": "0.18.5",
59
- "@testkit/effect-bun-test": "3.1.32-main.42864119477",
60
- "@tools/typescript-config": "3.1.32-main.42864119477",
59
+ "@testkit/effect-bun-test": "3.1.32-main.42894513068",
60
+ "@tools/typescript-config": "3.1.32-main.42894513068",
61
61
  "@types/bun": "1.4.4",
62
62
  "publint": "0.3.25"
63
63
  },
@@ -259,6 +259,30 @@ export function buildErrorCta(input: {
259
259
  };
260
260
  }
261
261
 
262
+ function formatCtaCommand(cliName: string, entry: CliCtaCommand): { command: string; description?: string } {
263
+ if (typeof entry === "string") {
264
+ return { command: `${cliName} ${entry}` };
265
+ }
266
+ const prefixed = entry.command === cliName || entry.command.startsWith(`${cliName} `);
267
+ let command = prefixed ? entry.command : `${cliName} ${entry.command}`;
268
+ for (const [key, value] of Object.entries(entry.args ?? {})) {
269
+ command += value === true ? ` <${key}>` : ` ${String(value)}`;
270
+ }
271
+ for (const [key, value] of Object.entries(entry.options ?? {})) {
272
+ command += value === true ? ` --${key} <${key}>` : ` --${key} ${String(value)}`;
273
+ }
274
+ return entry.description === undefined ? { command } : { command, description: entry.description };
275
+ }
276
+
277
+ export function renderCtaText(cliName: string, block: CliCtaBlock): string {
278
+ const commands = block.commands.map((entry) => formatCtaCommand(cliName, entry));
279
+ const width = Math.max(0, ...commands.map((entry) => entry.command.length));
280
+ const lines = commands.map((entry) =>
281
+ entry.description === undefined ? ` ${entry.command}` : ` ${entry.command.padEnd(width)} # ${entry.description}`
282
+ );
283
+ return [block.description, ...lines].join("\n");
284
+ }
285
+
262
286
  export function buildSuccessCtaFromResult(result: unknown): CliCtaBlock | undefined {
263
287
  const links = extractResourceLinks(result);
264
288
  const commands = commandsFromLinks(links);
@@ -1,6 +1,6 @@
1
1
  import type { DalpClient } from "@settlemint/dalp-sdk";
2
2
  import { Cli, z } from "incur";
3
- import { buildErrorCta, buildSuccessCtaFromResult, type CliCtaBlock } from "./cli-cta.ts";
3
+ import { buildErrorCta, buildSuccessCtaFromResult, renderCtaText, type CliCtaBlock } from "./cli-cta.ts";
4
4
  import { createCliStatus } from "./cli-status.ts";
5
5
  import { renderSdkErrorForCli } from "./errors.ts";
6
6
  import { INDEX_COMMAND } from "@settlemint/dalp-sdk/routes";
@@ -40,6 +40,14 @@ function withSuccessCta<T extends object>(context: T, data: unknown): unknown {
40
40
 
41
41
  export type ApiBag = LooseBag;
42
42
 
43
+ interface CliRefusal {
44
+ readonly code: string;
45
+ readonly message: string;
46
+ readonly retryable?: boolean;
47
+ readonly exitCode?: number;
48
+ readonly cta?: CliCtaBlock;
49
+ }
50
+
43
51
  interface McpAnnotations {
44
52
  readonly readOnlyHint: boolean;
45
53
  readonly destructiveHint?: boolean;
@@ -274,17 +282,18 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
274
282
  options?: unknown;
275
283
  request?: Request;
276
284
  agent?: boolean;
277
- error: (error: {
278
- code: string;
279
- message: string;
280
- retryable?: boolean;
281
- exitCode?: number;
282
- cta?: CliCtaBlock;
283
- }) => unknown;
285
+ displayName?: string;
286
+ error: (error: { code: string; message: string; retryable?: boolean; exitCode?: number }) => unknown;
284
287
  }) {
288
+ const refuseWithGuidanceInMessage = ({ cta, ...error }: CliRefusal) =>
289
+ c.error(
290
+ cta === undefined
291
+ ? error
292
+ : { ...error, message: `${error.message}\n\n${renderCtaText(c.displayName ?? "dalp", cta)}` }
293
+ );
285
294
  const { client } = c.var;
286
295
  if (client === undefined) {
287
- return c.error({
296
+ return refuseWithGuidanceInMessage({
288
297
  code: "NOT_AUTHENTICATED",
289
298
  message: "Not logged in. Run 'dalp login' to authenticate.",
290
299
  retryable: true,
@@ -325,7 +334,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
325
334
  if (failedEvent !== undefined) {
326
335
  yield failedEvent;
327
336
  }
328
- return c.error({
337
+ return refuseWithGuidanceInMessage({
329
338
  code: "kit.cli.MISSING_PATH",
330
339
  message: `Operation ${descriptor.name} requires path parameters.`,
331
340
  retryable: true,
@@ -347,7 +356,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
347
356
  yield failedEvent;
348
357
  }
349
358
  const message = error instanceof Error ? error.message : "Invalid path parameters";
350
- return c.error({
359
+ return refuseWithGuidanceInMessage({
351
360
  code: "kit.cli.INVALID_PATH",
352
361
  message,
353
362
  retryable: true,
@@ -375,7 +384,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
375
384
  yield failedEvent;
376
385
  }
377
386
  const message = error instanceof Error ? error.message : "Invalid query parameters";
378
- return c.error({
387
+ return refuseWithGuidanceInMessage({
379
388
  code: "kit.cli.INVALID_QUERY",
380
389
  message,
381
390
  retryable: true,
@@ -401,7 +410,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
401
410
  yield failedEvent;
402
411
  }
403
412
  const message = error instanceof Error ? error.message : "Invalid request body";
404
- return c.error({
413
+ return refuseWithGuidanceInMessage({
405
414
  code: "kit.cli.INVALID_BODY",
406
415
  message,
407
416
  retryable: true,
@@ -425,7 +434,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
425
434
  }
426
435
 
427
436
  const result = await runCommand(
428
- c,
437
+ { error: refuseWithGuidanceInMessage },
429
438
  invokeOperation(
430
439
  descriptor,
431
440
  client,
@@ -481,7 +490,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
481
490
  if (failed !== undefined) {
482
491
  yield failed;
483
492
  }
484
- return c.error({
493
+ return refuseWithGuidanceInMessage({
485
494
  ...rendered,
486
495
  exitCode: 1,
487
496
  });
@@ -518,7 +527,7 @@ function makeLeafHandler(ops: ReadonlyArray<OperationDescriptor>) {
518
527
  if (failed !== undefined) {
519
528
  yield failed;
520
529
  }
521
- return c.error({
530
+ return refuseWithGuidanceInMessage({
522
531
  ...rendered,
523
532
  exitCode: 1,
524
533
  });